垃圾回收與算法

 

 1.1 如何肯定垃圾算法

1.1.1 引用計數法3d

在Java中,引用和對象是有關聯的。若是要操做對象則必須用引用進行。所以,很顯然一個簡單的辦法是經過引用計數來判斷一個對象是否能夠回收。簡單說,即一個對象若是沒有任何與之關聯的引用,即他們的引用計數都不爲0,則說明對象不太可能再被用到,那麼這個對象就是可回收對象。對象

1.1.2 可達性分析blog

爲了解決引用計數法的循環引用問題,Java使用了可達性分析的方法。經過一系列的「GC roots」對象做爲起點搜索。若是在「GC roots」和一個對象之間沒有可達路徑,則稱該對象是不可達的。要注意的是,不可達對象不等價於可回收對象,不可達對象變爲可回收對象至少要通過兩次標記過程。兩次標記後仍然是可回收對象,則將面臨回收。內存

1.2標記清除算法(Mark-Sweep)虛擬機

最基礎的垃圾回收算法,分爲兩個階段,標註和清除。標記階段標記出全部須要回收的對象,清除階段回收被標記的對象所佔用的空間。如圖io

 

 從圖中咱們就能夠發現,該算法最大問題是內存碎片化嚴重,後續可能發生大對象不能找到可可用空間的問題。class

1.3複製算法(copying)效率

爲了解決Mark-Sweep算法內存碎片化的缺陷而被提出的算法。按內存容量將內存劃分爲等大小的兩塊。每次只使用其中一塊,當這一塊內存滿後將尚存活的對象複製到另外一塊上去,把已使用的內存清掉,如圖:基礎

 

 這中算法雖然實現簡單,內存效率高,不易產生碎片,可是最大的問題實施可用內存被壓縮到了本來的一半。且存活對象增多的話,Copying算法的效率會大大下降。

1.4 標記整理算法(Mark-Compact)

結合了以上兩個算法,爲了不缺陷而退出。標記階段和Mark-Sweep算法相同,標記後不是清理對象,而是將存活對象移向內存的一端。而後清除端邊界外的對象。如圖:

 

 1.5 分代收集算法

分代收集法是目前大部分JVM所採用的方法,其核心思想是根據對象存活的不一樣聲明週期將內存劃分爲不一樣的域,通常狀況下將GC堆劃分爲老生代(Tenured/Old Generation)和新生代(Young Generation)。老生代的特色是每次垃圾回收時只有少許對象須要被回收,新生代的特色是每次垃圾回收時都有大量垃圾須要被回收,所以能夠根據不一樣區域選擇不一樣算法。

1.5.1新生代複製算法

目前大部分JVM的GC對於新生代都採起Copying算法,由於新生代中每次垃圾回收都要回收大部分對象,即要複製的操做比較少,但一般並非按照1:1來劃分新生代。通常將新生代劃分爲一塊較大的Eden空間和兩個較小的Survivor空間(From Space,To Space),每次使用Eden空間和其中一塊Survivor空間,當進行回收時,將兩塊空間中還存活的對象複製到另外一塊Survivor空間中。

 

 1.5.2老年代與標記複製算法

而老年代由於每次只回收少許對象,於是採用Mark-Compact算法。

1.JAVA虛擬機提到過得處於方法區的永生代(Permanet Generation),它用來存儲class類,常量,方法描述等。對永生代的回收主要包括廢棄常量和無用的類

2.對象的內存分配主要在新生代的Eden Space 和Survivor Space的From Space(Survivor目前存放對象的那一塊),少數狀況直接分配到老生代。

3.當新生代的Eden Space和From Space空間不足時就會發生一次GC,進行GC後,Eden Spac和From SPace區的存活對象會被挪到To Space,而後將Eden Spac和From Space進行清理。

4.若是To Space沒法足夠存儲某個對象,則將這個對象存儲到老生代。

5.在進行GC後,使用的即是Eden Space 和To Space了,如此反覆循環。

6.當對象在Survivor區躲過一次GC後,其年齡就會+1.默認狀況下年齡到達15 的對象會被移到老生代中

相關文章
相關標籤/搜索