JVM中各個垃圾收集器的使用場景
在以往的文章中(垃圾收集算法)诬辈,我們講述了JVM中垃圾收集算法,像標(biāo)記-清除趴乡、標(biāo)記-整理对省、復(fù)制、分代等算法晾捏,這些只是垃圾收集的方法論蒿涎,今天要介紹的就是垃圾收集的具體實現(xiàn)---垃圾收集器。
垃圾收集器主要用于堆內(nèi)存中惦辛,先從一張圖中看下堆中老年代和新生代所適合的垃圾收集器劳秋,JDK11出來的ZGC不在其中。
Serial胖齐、ParNew玻淑、Parallel Scavenge用于新生代;CMS呀伙、Serial Old补履、Paralled Old用于老年代。 并且他們相互之間以相對固定的組合使用剿另。G1是一個獨立的收集器不依賴其他6種收集器箫锤。
1、Serial收集器雨女,是單線程執(zhí)行垃圾回收的麻汰,是JDK1.3之前新生代收集的唯一選擇。當(dāng)需要執(zhí)行垃圾回收時戚篙,程序會暫停一切手上的工作五鲫,然后單線程執(zhí)行垃圾回收。因為新生代的特點是對象存活率低岔擂,所以收集算法用的是復(fù)制算法位喂,把新生代存活對象復(fù)制到老年代,復(fù)制的內(nèi)容不多乱灵,性能較好塑崖。
2、Serial Old收集器痛倚,老年代的收集器规婆,與Serial一樣是單線程,不同的是算法用的是標(biāo)記-整理(Mark-Compact),因為老年代里面對象的存活率高抒蚜,如果依舊是用復(fù)制算法掘鄙,需要復(fù)制的內(nèi)容較多,性能較差嗡髓。并且在極端情況下操漠,當(dāng)存活為100%時,沒有辦法用復(fù)制算法饿这。所以需要用Mark-Compact浊伙,以有效地避免這些問題。這個收集器的主要意義也是被Client模式下的虛擬機(jī)使用长捧。如果是Server模式下嚣鄙,它的用途有兩個:一是在JDK1.5版本及之前版本與Parallel Scavenge收集器搭配使用,另外一個就是CMS收集器的后備預(yù)案串结,在并發(fā)收集發(fā)生Concurrent Mode Failure使用哑子。
下圖是Serial/Serial Old收集器運行示意圖:
3、ParNew收集器奉芦,ParNew同樣用于新生代赵抢,是Serial的多線程版本剧蹂,并且在參數(shù)、算法(同樣是復(fù)制算法)上也完全和Serial相同。Par是Parallel的縮寫家厌,但它的并行僅僅指的是收集多線程并行芜赌,并不是收集和原程序可以并行進(jìn)行。ParNew也是需要暫停程序一切的工作冒冬,然后多線程執(zhí)行垃圾回收伸蚯。
4、Parallel Scavenge收集器简烤,新生代的收集器剂邮,同樣用的是復(fù)制算法,也是并行多線程收集横侦。與ParNew最大的不同挥萌,它關(guān)注的是垃圾回收的吞吐量。這里的吞吐量指的是 總時間與垃圾回收時間的比例枉侧。這個比例越高引瀑,證明垃圾回收占整個程序運行的比例越小。
5榨馁、Parallel Old收集器憨栽,老年代的收集器,是Parallel Scavenge老年代的版本。其中的算法替換成Mark-Compact屑柔,標(biāo)記-整理算法屡萤。Parallel Old收集器出現(xiàn)后,“吞吐量優(yōu)先”收集器終于有了比較不錯的應(yīng)用組合锯蛀,在注重吞吐量及CPU資源敏感的場合灭衷,可以優(yōu)先考慮Parallel Scavenge收集器+Parallel Old收集器。
下圖就是Parallel Scavenge/Parallel Old收集器的運行示意圖:
6旁涤、CMS收集器翔曲,同樣是老年代的收集器。它關(guān)注的是垃圾回收最短的停頓時間(低停頓)劈愚,在老年代并不頻繁GC的場景下瞳遍,是比較適用的。用的是Mark Sweep菌羽,標(biāo)記-清除算法掠械。運行過程一共分為四步:初始標(biāo)記-并發(fā)標(biāo)記-重新標(biāo)記-并發(fā)清理。其中初始標(biāo)記和重新標(biāo)記仍需要STW注祖,不過速度很快猾蒂,耗時最長的是并發(fā)標(biāo)記和并發(fā)清理,由于是并發(fā)的執(zhí)行是晨,效率很高肚菠。
下圖是CMS收集器運行示意圖:
7、G1收集器罩缴,在JDK 1.7版本正式啟用蚊逢,是當(dāng)時最前沿的垃圾收集器。G1可以說是CMS的終極改進(jìn)版箫章,解決了CMS內(nèi)存碎片烙荷、更多的內(nèi)存空間登問題。雖然流程與CMS比較相似檬寂,但底層的原理已是完全不同终抽。高效益優(yōu)先。G1會預(yù)測垃圾回收的停頓時間桶至,原理是計算老年代對象的效益率昼伴,優(yōu)先回收最大效益的對象。堆內(nèi)存結(jié)構(gòu)的不同塞茅。以前的收集器分代是劃分新生代亩码、老年代、持久代等野瘦。G1則是把內(nèi)存分為多個大小相同的區(qū)域Region描沟,每個Region擁有各自的分代屬性飒泻,但這些分代不需要連續(xù)。
另外:伴隨著JDK11的到來吏廉,也帶來了一款新的垃圾收集器-ZGC泞遗,能處理TB級別的堆空間,這是要上天呀席覆,TB級別史辙。不過目前只支持在Linux平臺上。ZGC給Hotspot Garbage Collectors增加了兩種新技術(shù):著色指針和讀屏障佩伤,這里不做過多解析聊倔。
下面圖片給出的是設(shè)置垃圾收集常用的參數(shù):