HotSpot VM GC收集器的易混淆的名稱問題

最近分析HotSpot VM GC日誌,就各類收集器的名稱搞暈掉了,幸虧參考R大(RednaxelaFX )一些回覆和文章。整理在此文,以方便自已往後查閱,也可以讓有須要的同窗少走彎路,追本溯源,一切從DefNew的來因提及。算法


DefNew: 是使用-XX:+UseSerialGC(新生代,老年代都使用串行回收收集器)時啓用oracle

ParNew是使用-XX:+UseParNewGC(新生代使用並行收集器,老年代使用串行回收收集器)或者-XX:+UseConcMarkSweepGC(新生代使用並行收集器,老年代使用CMS)時啓用框架

 

本來HotSpotVM裏並無並行GC,當時只有NewGeneration。新生代,老年代都使用串行回收收集。後來準備加入新生代並行GC,就把NewGeneration更名爲DefNewGeneration,而後把新加的並行版叫作ParNewGenerationide

 

DefNewGenerationParNewGeneration都在Hotspot VM」分代式GC框架「內。但後來有個開發不肯意被這個框加憋着(證實了那句:全部壯舉都不是在框架內產生的),自已硬寫了個新的並行GC。測試後效果還不錯。因而這個也放入VMGC中。這就是咱們如今看到的ParallelScavenge性能

 

這個時候就出現個兩個新生代的並行GC收集器:ParNewGenerationParallelScavenge測試

 

(R大: Scavenge或者叫scavenging GC,其實就是copying GC的另外一種叫法而已。HotSpot VM裏的GC都是在minor GC收集器裏用scavenging的,DefNewParNewParallelScavenge都是,只不過DefNew是串行的copying GC,然後二者是並行的copying GC 由此名字就能夠知道,「ParallelScavenge」的初衷就是把「scavenge」給並行化。換句話說就是把minor GC並行化。至於full GC,那不是當初關注的重點。 )優化

 

GC並行化的目的是想提升GC速度,也就是提升吞吐量(throughput)。因此其實ParNewParallelScavenge均可叫作Throughput GC 
可是在HotSpot VM的術語裏「Throughput GC」一般特指「ParallelScavenge」
spa

 

ParallelScavengeParNew都是並行GC,主要是並行收集young gen,目的和性能其實都差很少。最明顯的區別有下面幾點:日誌

 

  1.   ParallelScavenge之前是廣度優先順序來遍歷對象圖的,JDK6的時候改成默認用深度優先順序遍歷,並留有一個UseDepthFirstScavengeOrder參數來選擇是用深度仍是廣度優先。在JDK6u18以後這個參數被去掉,ParallelScavenge變爲只用深度優先遍歷。ParNew則是一直都只用廣度優先順序來遍歷。orm

  2.   ParallelScavenge完整實現了adaptive size policy,而ParNew分代式GC框架內的其它GC都沒有實現(倒不是不能實現,就是麻煩+沒人力資源去作)。因此千萬千萬別在用ParNew+CMS的組合下用UseAdaptiveSizePolicy,請只在使用UseParallelGCUseParallelOldGC的時候用它。 

  3.  因爲在分代式GC框架內,ParNew能夠跟CMS搭配使用,而ParallelScavenge不能。當時ParNew GC被從Exact VM移植到HotSpot VM的最大緣由就是爲了跟CMS搭配使用。 

  4.   ParallelScavenge成爲主要的throughput GC以後,它還實現了針對NUMA的優化;而ParNew一  直沒有獲得NUMA優化的實現

 

上面說ParallelScavenge並行收集young gen,那old/perm gen呢? 

 

ParallelScavenge由於和其餘幾個GC不在一個框架內,最初的ParallelScavenge體系對老年代的回收拿的是VM的分代式框架「裏在 Serial Old收集器的代碼,改了接口,負責full GC

並命名爲: PSMarkSweep(=「ParallelScavengeMarkSweep」),其實就是仍然串行收集。

這裏的ParallelScavenge已經不是Parallel Scavenge(並行新生代收集器),而是一套GC框架體系。

 

爲了名稱與VM分代式框架」裏的收集器好區別,在這套體系時,新生代收集器叫:PSScavenge,老年代收集器叫:PSMarkSweep(PS當作是ParallelScavenge縮寫,做爲前綴)

 

後來,由於未知的緣由,老年代GC的並行化,沒有在VM分代式GC框架「中完成,而選擇了在ParallelScavenge框架中。其成果就是使用了LISP2算法的並行版的full GC收集器,名爲PSCompact(=「ParallelScavenge-MarkCompact」),收集整個GC

 

當啓用-XX:+UseParallelOldGC時,用的就是PSScavenge+PSCompact的組合

當啓用-XX:+UseParallelGC時,用的就是PSScavenge+ PSMarkSweep的組合

(在Jconsole查看時,PSCompactPSMarkSweep都顯示爲PSMarkSweep

  DefNew顯示爲Copy,Serial Old(MSC)顯示爲MarkSweepCompact)。


 Guest Author有一幅關於GC收集器的示意圖:

wKiom1mJg3Hw-ClQAAE6RDl8LR8949.png-wh_50

×××部分的用於新生代的收集器,紫灰色部分的用於老年代的收集器。鏈接線表示二者能夠配合使用。


你會發現分代式GC框架有收集器(Serial (就是DefNew),ParNewCMSMSC)能夠任意搭配。而ParallelScavenge體系裏的PSScavenge(圖示中的ParallelScavenge),只能和其同一體系的Parallel Old搭配

至於ParallelScavengeSerial Old的連線,就是由於上文提到的PSMarkSweep,他是從VM分代式框架「裏抽出來的Serial Old收集器,加了一層包裝而已。

 

?號那個應該就是如今G1,他又是另外一個體系框架內開發的,因此六親不認

相關文章
相關標籤/搜索