1. 程式人生 > >Java 虛擬機器 gc演算法總結

Java 虛擬機器 gc演算法總結

一、垃圾收集基本的演算法

1. 引用計數(Reference Counting)

為每一個物件新增一個計數器,計數器記錄了對該物件的活躍引用的數量。如果計數器為0,則說明這個物件沒有被任何變數所引用,即應該進行垃圾收集。
收集過程如下:
1)減少被收集物件所引用的物件的計數器的值
2)將其放入延時收集佇列之中

引用計數的方法需要編譯器的配合。編譯器需要為此物件生成額外的程式碼。如賦值函式將此物件賦值給一個引用時,需要增加此物件的引用計數。還有就是,當一個引用變數的生命週期結束時,需要更新此物件的引用計數器。引用計數的方法由於存在顯著的缺點,實際上並未被JVM所使用。

2. 標記-清除收集器(Mark-Swap Collectors)

收集過程分為2個階段
1)首先停止所有工作,從根集遍歷所有被引用的節點,然後進行標記,最後恢復所有工作
2)收集階段會收集那些沒有被標記的節點,然後返回空閒連結串列

標記-清除法的缺點在於
1)標記階段暫停的時間可能很長,而整個堆在交換階段又是可訪問的,可能會導致被換頁換出記憶體。
2)另外一個問題在於,不管你這個物件是不是可達的,即是不是垃圾,都要在清楚階段被檢查一遍,非常耗時.
3)標記清楚這兩個動作會產生大量的記憶體碎片,於是當有大物件進行分配時,不需要觸發一次垃圾回收動作

3. 拷貝收集器(Copying Collectors)

該演算法的提出是為了克服控制代碼的開銷和解決堆碎片的垃圾回收。將記憶體分為兩個區域(fromspace和tospace)。所有的物件分配記憶體都分配到fromspace。在清理非活動物件階段,把所有標誌為活動的物件,copy到tospace,之後清楚fromspace空間。然後互換fromsapce和tospace的身份。既原先的fromspace變成tosapce,原先的tospace變成fromspace。每次清理,重複上述過程。
現在的商業虛擬機器都用這種演算法來回收新生代,因為新生代的大多數的生命週期都很短暫,所以前面提到的兩塊相互切換的區域並不需要按照1:1來進行分配。而是分配了一個Eden區,兩個Survivor區。大部分物件預設的都是在Eden區中生成。當垃圾回收時,Eden和其中的一個Survivor區的存活物件將被複制到另外一個Survivor區,當另外一個Survivor區也滿了的時候,從Eden和第一個Survivor區複製過來的並且此時還存活的物件,將被複制到tenured。


4. 標記-整理收集器(Mark-Compact Collectors)(適用於存放生命週期較長物件的tenured generation:PSOldGen)
標記整理收集器,通過融合了標記-清除收集器和拷貝收集器的優點,很好的解決了拷貝收集策略中,堆記憶體浪費嚴重的問題。
標記整理收集器分為2個階段
1)標記階段,這個階段和標記-清除收集器的標記階段相同
2)整理階段,這個階段將所有做了標記的活動物件整理到堆的底部

分代總結:生命週期較長的物件,歸入到tenured generation。一般是經過多次minor gc,還 依舊存活的物件,將移入到tenured generation。(當然,在minor gc中如果存活的物件的超過survivor的容量,放不下的物件會直接移入到tenured generation)tenured generation的gc稱為major gc,就是通常說的full gc。由於tenured generaion區域比較大,而且通常物件生命週期都比較長,所以這部分的gc時間比較長。minor gc可能引發full gc。當eden+from space的空間大於tenured generation區的剩餘空間時,會引發full gc。這是悲觀演算法,要確保eden+from space的物件如果都存活,必須有足夠的tenured generation空間存放這些物件。

2、Java HotSpot VM 年輕代和年老代垃圾回收演算法

1. 年輕代:

1)Serial(序列的複製演算法,對應GC log 為 DefNew)

2)ParNew(多執行緒的Serial複製演算法,對應GC log 為 ParNew)

3)PS(多執行緒的複製演算法,關注吞吐量的改善,對應GC log 為 PSYounGen)

2. 年老代:

1)Serial MSC(序列的標記清除演算法,對應GC log為Tenured)

2)並行MSC(並行的標記清除演算法,對應GC log為PSOldGen)

3)並行Compating(並行的標記整理演算法,對應GC log為ParOldGen)

4)併發CMS(併發的標記清除演算法,對應GC log為CMS)

3、參考資料:

http://blog.csdn.net/eric_sunah/article/details/7866975

Sun JDK 1.6 Garbage Collector(作者:畢玄)