java垃圾回收機制

內存回收機制:

內存回收就是釋放掉在內存中已經沒用的對象。

首先,要判斷怎樣的對象是沒用的對象。這裏有2種方法:

1.採用標記計數的方法:

給內存中的對象給打上標記,對象被引用一次,計數就加1,引用被釋放了,計數就減一,當這個計數爲0的時候,這個對象就可以被回收了。當然,這也就引發了一個問題:循環引用的對象是無法被識別出來並且被回收的。所以就有了第二種方法:

2.採用根搜索算法

從一個根出發,搜索所有的可達對象,這樣剩下的那些對象就是需要被回收的

判斷完了哪些對象是沒用的,這樣就可以進行回收了

最簡單的,就是直接清空那個需要被回收的對象。但是這又出現了一個問題,就是內存會被分爲一塊一塊的小碎片。

爲了解決這個問題,可以採用第二種方法,就是在之前的基礎上將存活的對象給整理一下,使他們變成一個連續的內存,從而釋放出連續的較大的內存空間。

還有一中回收方法就是採用複製的辦法:將內存分爲2塊,一塊用來存放對象,另一塊用來放着,當存放對象的那塊滿了以後就將上面存活的對象給複製過來,然後在這塊內存上工作,並且將之前的內存清空,當自己這塊滿了以後再複製回去,如此反覆。


比較效率的一中做法是將以上的幾種方法給結合起來。

首先將內存分塊,分爲新生代,老年代和永久代。

永久代用來存放代碼,等一些基本不改變的數據,

新生代用來存放剛產生的一些對象,新生代又可分爲3塊。分別爲Edon區,Survivor0,survivor1,剛產生的對象是放在Edon區中,當這個區塊放滿了以後就將其存活的部分複製到survivor0塊中,並且將Edon區中的數據清空,等到survivor0滿了就將其中的存活的數據放到survivor1中,清空survivor0,垃圾回收到了一定次數還未被回收的對象,就可以放到老年區。一般來說,剛纔產生的對象大多是要在下一次垃圾回收的時候就要被回收掉的,只有一小部分對象會被保留下來,這些被保留下來的對象都是比較穩定的,所以在老年區中的對象回收方法可以採用整理的方法,而在Edon區等新生代中採用複製的方法比較好。


這裏,基本上就講完了。

萬一被問到還有呢。。想了想,還可以扯些其他方面的:

垃圾回收他是在虛擬機空閒的時候或者內存緊張的時候執行的,什麼時候回收不是由程序員來控制的,這也就是Java比較耗內存的原因之一。

還有在垃圾回收的時候當檢測到對象沒有用了,需要被回收的時候並不會馬上被回收,而是將其放入到一個準備回收的隊列,去執行finalize方法。。然等到下次內存回收的時候要是他還是沒有被任何人引用的話,就將其給回收了。(如果在finalize方法中重新給對象加個引用,這樣對象是有可能不會被回收的)不過finalize方法不推薦使用,他跟C++中的析構函數不同,我們既不能確定什麼時候他回被回收,也不能保證這個方法一定會被執行。

發佈了26 篇原創文章 · 獲贊 20 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章