JVM:7种垃圾回收器总结
這里討論的收集器基于JDK1.7Update 14之后的HotSpot虛擬機(jī),這個(gè)虛擬機(jī)包含的所有收集器如下圖3-5所示:
?
上圖展示了7種作用于不同分代的收集器,如果兩個(gè)收集器之間存在連線,就說明它們可以搭配使用。
所謂垃圾收集器在準(zhǔn)確完整回收垃圾對(duì)象內(nèi)存的基礎(chǔ)上,所追求的目標(biāo)是
1)縮短Stop-The-World 的停頓時(shí)間
2)盡可能使得垃圾收集線程和用戶線程同時(shí)并發(fā)執(zhí)行!!!那么也就不存在停頓!這是終極目標(biāo)!!!!
1.Serial收集器
Serial收集器是最基本、發(fā)展歷史最悠久的收集器。是單線程的收集器。它在進(jìn)行垃圾收集時(shí),必須暫停其他所有的工作線程,直到它收集完成。
采用的是復(fù)制算法
?
Serial收集器依然是虛擬機(jī)運(yùn)行在Client模式下默認(rèn)新生代收集器,對(duì)于運(yùn)行在Client模式下的虛擬機(jī)來說是一個(gè)很好的選擇。
?
2.ParNew收集器
ParNew收集器其實(shí)就是Serial收集器的多線程版本,除了使用多線程進(jìn)行垃圾收集之外,其余行為包括Serial收集器可用的所有控制參數(shù)、收集算法、Stop The Worl、對(duì)象分配規(guī)則、回收策略等都與Serial?收集器完全一樣。
采用的也是復(fù)制算法
?
ParNew收集器是許多運(yùn)行在Server模式下的虛擬機(jī)中首選新生代收集器,其中有一個(gè)與性能無(wú)關(guān)但很重要的原因是,除Serial收集器之外,目前只有ParNew它能與CMS收集器配合工作。
?
3.Parallel Scavenge收集器? ?-------->追求高的吞吐量
它也是使用復(fù)制算法的收集器
Parallel Scavenge收集器是一個(gè)新生代收集器,又是并行的多線程收集器
該收集器的目標(biāo)是達(dá)到一個(gè)可控制的吞吐量(Throughput)。所謂吞吐量就是CPU用于運(yùn)行用戶代碼的時(shí)間與CPU總消耗時(shí)間的比值,即 吞吐量=運(yùn)行用戶代碼時(shí)間/(運(yùn)行用戶代碼時(shí)間+垃圾收集時(shí)間)
吞吐量和停頓時(shí)間不可兼得!吞吐量越高,停頓時(shí)間就越長(zhǎng)!
停頓時(shí)間越短就越適合需要與用戶交互的程序,良好的響應(yīng)速度能提升用戶體驗(yàn),而高吞吐量則可用高效率地利用CPU時(shí)間,盡快完成程序的運(yùn)算任務(wù),主要適合在后臺(tái)運(yùn)算而不需要太多交互的任務(wù)。
Parallel Scavenge收集器提供兩個(gè)參數(shù)用于精確控制吞吐量,分別是控制最大垃圾收起停頓時(shí)間的
-XX:MaxGCPauseMillis參數(shù)以及直接設(shè)置吞吐量大小的-XX:GCTimeRatio參數(shù)
Parallel Scavenge收集器還有一個(gè)參數(shù):-XX:+UseAdaptiveSizePolicy。這是一個(gè)開關(guān)參數(shù),自適應(yīng)調(diào)節(jié),當(dāng)這個(gè)參數(shù)打開后,就不需要手工指定新生代的大小(-Xmn)、Eden與Survivor區(qū)的比例(-XX:SurvivorRatio)、晉升老年代對(duì)象年齡(-XX:PretenureSizeThreshold)等細(xì)節(jié)參數(shù),只需要把基本的內(nèi)存數(shù)據(jù)設(shè)置好(如-Xmx設(shè)置最大堆),然后使用MaxGVPauseMillis參數(shù)或GCTimeRation參數(shù)給虛擬機(jī)設(shè)立一個(gè)優(yōu)化目標(biāo)。
自適應(yīng)調(diào)節(jié)策略也是Parallel Scavenge收集器與ParNew收集器的一個(gè)重要區(qū)別
現(xiàn)在來介紹老年代的垃圾回收器
4.Serial Old?收集器
使用標(biāo)記整理算法
Serial Old是Serial收集器的老年代版本,它同樣是一個(gè)單線程收集器,使用標(biāo)記整理算法。這個(gè)收集器的主要意義也是在于給Client模式下的虛擬機(jī)使用。
如果在Server模式下,主要兩大用途:
(1)在JDK1.5以及之前的版本中與Parallel Scavenge收集器搭配使用
(2)作為CMS收集器的后備預(yù)案,在并發(fā)收集發(fā)生Concurrent Mode Failure時(shí)使用
Serial Old收集器的工作工程
?
?
5.Parallel Old?收集器
使用標(biāo)記整理算法
Parallel Old?是Parallel Scavenge收集器的老年代版本,使用多線程和“標(biāo)記-整理”算法。這個(gè)收集器在1.6中才開始提供。
?
Parallel Scavenge和Parallel Old 的組合能夠使得在充分利用多CPU的場(chǎng)景下實(shí)現(xiàn)吞吐量?jī)?yōu)先的最佳組合
?
6.CMS收集器
CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器。目前很大一部分的Java應(yīng)用集中在互聯(lián)網(wǎng)站或者B/S系統(tǒng)的服務(wù)端上,這類應(yīng)用尤其重視服務(wù)器的響應(yīng)速度,希望系統(tǒng)停頓時(shí)間最短,以給用戶帶來較好的體驗(yàn)。CMS收集器就非常符合這類應(yīng)用的需求
CMS收集器是基于“標(biāo)記-清除”算法實(shí)現(xiàn)的。會(huì)產(chǎn)生內(nèi)存碎片
它的運(yùn)作過程相對(duì)前面幾種收集器來說更復(fù)雜一些,整個(gè)過程分為4個(gè)步驟:
(1)初始標(biāo)記? ? ?需要停頓
(2)并發(fā)標(biāo)記
(3)重新標(biāo)記? ? ?需要停頓
(4)并發(fā)清除
其中,初始標(biāo)記、重新標(biāo)記這兩個(gè)步驟仍然需要“Stop The World”.
?
?
CMS收集器主要優(yōu)點(diǎn):并發(fā)收集,低停頓。
CMS三個(gè)明顯的缺點(diǎn):
(1)CMS收集器對(duì)CPU資源非常敏感。CPU個(gè)數(shù)少于4個(gè)時(shí),CMS對(duì)于用戶程序的影響就可能變得很大,為了應(yīng)付這種情況,虛擬機(jī)提供了一種稱為“增量式并發(fā)收集器”的CMS收集器變種。所做的事情和單CPU年代PC機(jī)操作系統(tǒng)使用搶占式來模擬多任務(wù)機(jī)制的思想。在并發(fā)階段雖然不會(huì)導(dǎo)致用戶線程停頓,但是會(huì)因?yàn)檎加昧艘徊糠志€程使應(yīng)用程序變慢
(2)CMS收集器無(wú)法處理浮動(dòng)垃圾,可能出現(xiàn)“Concurrent Mode Failure”失敗而導(dǎo)致另一次Full GC的產(chǎn)生。在JDK1.5的默認(rèn)設(shè)置下,CMS收集器當(dāng)老年代使用了68%的空間后就會(huì)被激活,這是一個(gè)偏保守的設(shè)置,如果在應(yīng)用中藍(lán)年代增長(zhǎng)不是太快,可以適當(dāng)調(diào)高參數(shù)-XX:CMSInitiatingOccupancyFraction的值來提高觸發(fā)百分比,以便降低內(nèi)存回收次數(shù)從而獲取更好的性能,在JDK1.6中,CMS收集器的啟動(dòng)閥值已經(jīng)提升至92%。(并發(fā)清除的時(shí)候,用戶線程會(huì)產(chǎn)生垃圾)
(3)CMS是基于“標(biāo)記-清除”算法實(shí)現(xiàn)的收集器,手機(jī)結(jié)束時(shí)會(huì)有大量空間碎片產(chǎn)生。空間碎片過多,可能會(huì)出現(xiàn)老年代還有很大空間剩余,但是無(wú)法找到足夠大的連續(xù)空間來分配當(dāng)前對(duì)象,不得不提前出發(fā)FullGC。為了解決這個(gè)問題,CMS收集器提供了一個(gè)-XX:+UseCMSCompactAtFullCollection開關(guān)參數(shù)(默認(rèn)就是開啟的),用于在CMS收集器頂不住要進(jìn)行FullGC時(shí)開啟內(nèi)存碎片合并整理過程,內(nèi)存整理的過程是無(wú)法并發(fā)的,空間碎片問題沒有了,但停頓時(shí)間變長(zhǎng)了。虛擬機(jī)設(shè)計(jì)者還提供了另外一個(gè)參數(shù)-XX:CMSFullGCsBeforeCompaction,這個(gè)參數(shù)是用于設(shè)置執(zhí)行多少次不壓縮的Full GC后,跟著來一次帶壓縮的(默認(rèn)值為0,標(biāo)識(shí)每次進(jìn)入Full GC時(shí)都進(jìn)行碎片整理)
7. G1收集器
優(yōu)先回收價(jià)值最大的Region,所以取名Garbage First
G1收集器的優(yōu)勢(shì):
(1)并行與并發(fā)
(2)分代收集
(3)空間整理 (標(biāo)記整理算法,復(fù)制算法)
(4)可預(yù)測(cè)的停頓(G1處處理追求低停頓外,還能建立可預(yù)測(cè)的停頓時(shí)間模型,能讓使用者明確指定在一個(gè)長(zhǎng)度為M毫秒的時(shí)間片段內(nèi),消耗在垃圾收集上的時(shí)間不得超過N毫秒,這幾乎已經(jīng)實(shí)現(xiàn)Java(RTSJ)的來及收集器的特征)
?
使用G1收集器時(shí),Java堆的內(nèi)存布局是整個(gè)規(guī)劃為多個(gè)大小相等的獨(dú)立區(qū)域(Region),雖然還保留有新生代和老年代的概念,但新生代和老年代不再是物理隔離的了,它們都是一部分Region的集合。
G1收集器之所以能建立可預(yù)測(cè)的停頓時(shí)間模型,是因?yàn)樗梢杂杏?jì)劃地避免在真?zhèn)€Java堆中進(jìn)行全區(qū)域的垃圾收集。G1跟蹤各個(gè)Region里面的垃圾堆積的價(jià)值大小(回收所獲取的空間大小以及回收所需要的時(shí)間的經(jīng)驗(yàn)值),在后臺(tái)維護(hù)一個(gè)優(yōu)先列表,每次根據(jù)允許的收集時(shí)間,優(yōu)先回收價(jià)值最大的Region(這也就是Garbage-First名稱的由來)。這種使用Region劃分內(nèi)存空間以及有優(yōu)先級(jí)的區(qū)域回收方式,保證了G1收集器在有限的時(shí)間內(nèi)可以獲取盡量可能高的灰機(jī)效率
G1?內(nèi)存“化整為零”的思路
在GC根節(jié)點(diǎn)的枚舉范圍中加入Remembered Set即可保證不對(duì)全堆掃描也不會(huì)遺漏。
如果不計(jì)算維護(hù)Remembered Set的操作,G1收集器的運(yùn)作大致可劃分為一下步驟:
(1)初始標(biāo)記
(2)并發(fā)標(biāo)記? ? ?只有并發(fā)標(biāo)記階段無(wú)需停頓
(3)最終標(biāo)記
(4)篩選回收
?
總結(jié)
以上是生活随笔為你收集整理的JVM:7种垃圾回收器总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JVM:-Xmx和-Xms应该维持什么样
- 下一篇: JVM:四种引用总结