HotSpot VM GC收集器的合名問題
最近分析HotSpot VM GC日誌,就各種收集器的名稱搞暈掉了,幸好參考R大(RednaxelaFX )一些回復和文章。整理在此文,以方便自已日後查閱,也可讓有需要的同學少走彎路,追本溯源,一切從DefNew的來因說起。
DefNew: 是使用-XX:+UseSerialGC(新生代,老年代都使用串行回收收集器)
ParNew: 是使用-XX:+UseParNewGC(新生代使用並行收集器,老年代使用串行回收收集器)或者-XX:+UseConcMarkSweepGC(新生代使用並行收集器,老年代使用CMS)。
原本HotSpotVM裏並沒有並行GC,當時只有NewGeneration。新生代,老年代都使用串行回收收集。後來準備加入新生代並行
DefNewGeneration、ParNewGeneration都在Hotspot VM”分代式GC框架“內。但後來有個開發不願意被這個框加憋著(證明了那句:所有壯舉都不是在框架內產生的),自已硬寫了個新的並行GC。測試後效果還不錯。於是這個也放入VM的GC中。這就是我們現在看到的ParallelScavenge。
這個時候就出現個兩個新生代的並行GC收集器:ParNewGeneration,ParallelScavenge。
(R大: Scavenge或者叫
把GC並行化的目的是想提高GC速度,也就是提高吞吐量(throughput)。所以其實ParNew與ParallelScavenge
但是在HotSpot VM的術語裏“Throughput GC”通常特指“ParallelScavenge”。
ParallelScavenge和ParNew都是並行GC,主要是並行收集young gen,目的和性能其實都差不多。最明顯的區別有下面幾點:
ParallelScavenge以前是廣度優先順序來遍歷對象圖的,JDK6的時候改為默認用深度優先順序遍歷,並留有一個UseDepthFirstScavengeOrder參數來選擇是用深度還是廣度優先。在JDK6u18之後這個參數被去掉,ParallelScavenge變為只用深度優先遍歷。ParNew則是一直都只用廣度優先順序來遍歷。
ParallelScavenge完整實現了adaptive size policy,而ParNew及“分代式GC框架”內的其它GC都沒有實現完(倒不是不能實現,就是麻煩+沒人力資源去做)。所以千萬千萬別在用ParNew+CMS的組合下用UseAdaptiveSizePolicy,請只在使用UseParallelGC或UseParallelOldGC的時候用它。
由於在“分代式GC框架”內,ParNew可以跟CMS搭配使用,而ParallelScavenge不能。當時ParNew GC被從Exact VM移植到HotSpot VM的最大原因就是為了跟CMS搭配使用。
在ParallelScavenge成為主要的throughput GC之後,它還實現了針對NUMA的優化;而ParNew一 直沒有得到NUMA優化的實現。
上面說ParallelScavenge並行收集young gen,那old/perm gen呢?
ParallelScavenge因為和其他幾個GC不在一個框架內,最初的ParallelScavenge體系對老年代的回收拿的是“VM分代式框裏的“ Serial Old收集器,改了接口,負責full GC,
命名為: PSMarkSweep(=“ParallelScavenge的MarkSweep”),其實就是串行收。
這裏的ParallelScavenge已經不是Parallel Scavenge,而是一套GC框架體系。
為了名稱下好區別,在這套體系時,新生代收集器叫:PSScavenge,這時的老年代收集器叫:PSMarkSweep。(PS看成是ParallelScavenge縮寫,作為前綴)。
後來,因為未知的原因,老年代GC的並行化,沒有在”分代式GC框架“中完成,而選擇了在ParallelScavenge框架中。其成果就是使用了LISP2算法的並行版的full GC收集器,名為PSCompact(=“ParallelScavenge-MarkCompact”),收集整個GC堆。
當啟用-XX:+UseParallelOldGC時,用的就是PSScavenge+PSCompact的組合。
當啟用-XX:+UseParallelGC時,用的就是PSScavenge+ PSMarkSweep的組合。
(在Jconsole查看時,PSCompact、PSMarkSweep都顯示為PSMarkSweep)。
Guest Author有一幅關於GC收集器的示意圖:
黃色部分的用於新生代的收集器,紫灰色部分的用於老年代的收集器。連接表示兩個可以配合使用。
你會發現分代式GC框架有收集器(Serial (就是DefNew),ParNew,CMS,MSC)可以任意搭配。而ParallelScavenge體系裏的PSScavenge(圖示中的ParallelScavenge),只能和其同一體系的Parallel Old搭配。
至於ParallelScavenge和Serial Old的連線,就是因為上文提到的PSMarkSweep,他是從“VM分代式框裏的“ 抽出來的Serial Old收集器,加了一層包裝而已。
?號那個應該就是現在G1,他又是另一個體系框架內開發的,所以六親不認。
本文出自 “天下無賊” 博客,請務必保留此出處http://guojuanjun.blog.51cto.com/277646/1954570
HotSpot VM GC收集器的合名問題