7種垃圾收集器作用于不同的分代,如果兩個收集器之間存在連續(xù),就說明他們可以搭配使用肴熏。
從JDK1.3到現(xiàn)在,從Serial收集器-》Parallel收集器-》CMS-》G1乔遮,用戶線程停頓時間不斷縮短扮超,但仍然無法完全消除。
1蹋肮、Serial收集器(串行收集器)
Serial收集器是最基本出刷、發(fā)展歷史最悠久的收集器,曾是(JDK1.3.1之前)虛擬機新生代收集的唯一選擇坯辩。
Serial收集器是一個單線程的收集器馁龟。“單線程”的意義不僅僅是它只會使用一個CPU或一條收集器線程去完成垃圾收集工作漆魔,更重要的是它在垃圾收集的時候坷檩,必須暫停其他所有工作的線程,直到它收集結(jié)束改抡。
Serial收集器是HotSpot虛擬機運行在Client模式下的默認(rèn)新生代收集器矢炼。
Serial收集器具有簡單而高效,由于沒有線程交互的開銷阿纤,可以獲得最高的單線程收集效率(在單個CPU環(huán)境中)句灌。
"-XX:+UseSerialGC":添加該參數(shù)來顯式的使用Serial垃圾收集器。
2欠拾、ParNew收集器
ParNew收集器是Serial收集器的多線程版本胰锌,除了使用多條線程進(jìn)行垃圾收集之外,其余行為包括Serial收集器可用的所有控制參數(shù)藐窄、收集算法资昧、Stop The Word、對象分配規(guī)則荆忍、回收策略等都與Serial收集器一樣格带。
ParNew收集器是許多運行在Server模式下的虛擬機首選的新生代收集器,其中一個原因是刹枉,除了Serial收集器之外践惑,目前只有ParNew收集器能與CMS收集器配合工作。
"-XX:+UseConcMarkSweepGC":指定使用CMS后嘶卧,會默認(rèn)使用ParNew作為新生代收集器尔觉。
"-XX:+UseParNewGC":強制指定使用ParNew。
"-XX:ParallelGCThreads":指定垃圾收集的線程數(shù)量芥吟,ParNew默認(rèn)開啟的收集線程與CPU的數(shù)量相同侦铜。
并行(Parallel):指多條垃圾收集線程并行工作,但此時用戶線程仍然處于等待狀態(tài)钟鸵。
并發(fā)(Concurrent):指用戶線程與垃圾收集線程同時執(zhí)行(但不一定是并行箱玷,可能是交替執(zhí)行),用戶線程繼續(xù)工作旷祸,而垃圾收集程序運行在另一個CPU上熊榛。
3、Parallel Scavenge收集器
Parallel Scavenge收集器是一個新生代收集器,使用復(fù)制算法俊卤,且是并行的多線程收集器嫩挤。
Parallel Scavenge收集器關(guān)注點是達(dá)到一個可控制的吞吐量(吞吐量 = 運行用戶代碼時間 / (運行用戶代碼時間 + 垃圾收集時間)),而其他收集器關(guān)注點在盡可能的縮短垃圾收集時用戶線程的停頓時間消恍。
Parallel Scavenge收集器提供了兩個參數(shù)來用于精確控制吞吐量岂昭,一是控制最大垃圾收集停頓時間的 -XX:MaxGCPauseMillis參數(shù),二是控制吞吐量大小的 -XX:GCTimeRatio參數(shù)狠怨;
“ -XX:MaxGCPauseMillis” 參數(shù)允許的值是一個大于0的毫秒數(shù)约啊,收集器將盡可能的保證內(nèi)存垃圾回收花費的時間不超過設(shè)定的值(但是,并不是越小越好佣赖,GC停頓時間縮短是以犧牲吞吐量和新生代空間來換取的恰矩,如果設(shè)置的值太小,將會導(dǎo)致頻繁GC憎蛤,這樣雖然GC停頓時間下來了外傅,但是吞吐量也下來了)。
“ -XX:GCTimeRatio”參數(shù)的值是一個大于0且小于100的整數(shù)蹂午,也就是垃圾收集時間占總時間的比率栏豺,默認(rèn)值是99,就是允許最大1%(即1/(1+99))的垃圾收集時間豆胸。
“-XX:UseAdaptiveSizePolicy”參數(shù)是一個開發(fā)奥洼,如果這個參數(shù)打開之后,虛擬機會根據(jù)當(dāng)前系統(tǒng)運行情況收集監(jiān)控信息晚胡,動態(tài)調(diào)整新生代的比例灵奖、老年代大小等細(xì)節(jié)參數(shù),以提供最合適的停頓時間或最大的吞吐量估盘,這種調(diào)節(jié)方式稱為GC自適應(yīng)的調(diào)節(jié)策略瓷患。
4、Serial Old收集器
Serial Old收集器是Seria收集器的老年代版本遣妥,他同樣是一個單線程收集器擅编,使用" 標(biāo)記-整理" 算法。
Serial Old收集器主要用于Client模式下的虛擬機使用箫踩。
Server模式下的兩大用途:一爱态、在JDK1.5及之前的版本與Parallel Scavenge收集器搭配使用;二境钟、作為CMS收集器的后備方案锦担,在并發(fā)收集發(fā)生Conturrent Mode Failure時使用。
5慨削、Paraller Old收集器
Parallel Old收集器是Parallel Scavenge收集器的老年代版本洞渔,使用多線程和“標(biāo)記-整理”算法套媚。
在JDK1.6中才出現(xiàn)。
6磁椒、CMS(Conturrent Mark Sweep)收集器
CMS收集器是一種以獲取最短回收停頓時間為目標(biāo)的收集器堤瘤。
目前很大一部分的Java應(yīng)用集中在互聯(lián)網(wǎng)或者B/S系統(tǒng)的服務(wù)端上。
CMS收集器是基于“標(biāo)記-清除”算法實現(xiàn)衷快,它的整個運行過程可以分為:初始登記(標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對象宙橱,這個過程速度很快)姨俩、并發(fā)標(biāo)記(進(jìn)行GCRoots Tracing的過程)蘸拔、重新標(biāo)記(修正并發(fā)標(biāo)記期間因用戶線程繼續(xù)運作而導(dǎo)致標(biāo)記產(chǎn)生變動的那一部分對象的標(biāo)記記錄,速度稍慢)环葵、并發(fā)清除(清除死亡的對象)4個步驟调窍;其中,初始標(biāo)記和重新標(biāo)記仍然需要“Stop The World”张遭。
CMS收集器運行的整個過程中邓萨,最耗費時間的并發(fā)標(biāo)記和并發(fā)清楚過程收集器線程和用戶線程是一起工作的,所以總體來說菊卷,CMS收集器的內(nèi)存回收過程是與用戶線程一起并發(fā)執(zhí)行的缔恳。
優(yōu)點:并發(fā)收集、低停頓洁闰。
缺點:
一:CMS收集器對CPU資源非常敏感歉甚。雖然在兩個并發(fā)階段不會導(dǎo)致用戶線程停頓,但是會因為占用了一部分線程而導(dǎo)致應(yīng)用程序變慢扑眉,總吞吐量下降纸泄。CMS默認(rèn)啟動的回收線程數(shù)是(CPU數(shù)量+3)/4。
二:CMS收集器無法處理浮動垃圾腰素,可能出現(xiàn)“Conturrent Mode Failure”失敗而導(dǎo)致另一次Full GC產(chǎn)生聘裁。由于CMS并發(fā)清除階段用戶線程還在運行,伴隨著程序還在產(chǎn)生新的垃圾弓千,這一部分垃圾出現(xiàn)在標(biāo)記之后衡便,CMS無法在當(dāng)次收集中處理掉它們,只能留到下次再清理洋访,這一部分垃圾稱為“浮動垃圾”镣陕。也正是由于在垃圾收集階段用戶線程還在運行,那么也就需要預(yù)留有足夠的內(nèi)存空間給用戶線程使用捌显,因此CMS收集器不能像其他收集器那樣等待老年代填滿之后再進(jìn)行收集茁彭,需要預(yù)留一部分空間給并發(fā)收集時用戶程序使用》鐾幔可以通過“-XX:CMSInitiatingOccupancyFraction”參數(shù)設(shè)置老年代內(nèi)存使用達(dá)到多少時啟動收集理肺。
三:由于CMS收集器是一個基于“標(biāo)記-清除”算法的收集器摄闸,那么意味著收集結(jié)束會產(chǎn)生大量碎片,有時候往往還有很多內(nèi)存未使用妹萨,可是沒有一塊連續(xù)的空間來分配一個對象年枕,導(dǎo)致不得不提前觸發(fā)一次Full GC。CMS收集器提供了一個“-XX:UseCMSCompactAtFullCollection”參數(shù)(默認(rèn)是開啟的)用于在CMS收集器頂不住要FullGC時開啟內(nèi)存碎片整理(內(nèi)存碎片整理意味著無法并發(fā)執(zhí)行不得不停頓用戶線程)乎完。參數(shù)“-XX:CMSFullGCsBeforeCompaction”來設(shè)置執(zhí)行多少次不壓縮的Full GC后熏兄,跟著來一次帶壓縮的(默認(rèn)值是0,意味著每次進(jìn)入Full GC時都進(jìn)行碎片整理)树姨。
7摩桶、G1(Garbage-First)收集器
G1收集器是當(dāng)今收集器技術(shù)發(fā)展的最前沿成果之一;
相比其它收集器帽揪,具有如下特點:
1硝清、并行與并發(fā):G1能夠重發(fā)利用多CPU、多核環(huán)境下的優(yōu)勢转晰,使用多個CPU來縮短Stop-The-World停頓時間芦拿。
2、分代收集:與其他收集器一樣查邢,分代概念在G1中依然存在蔗崎。
3、空間整合:與CMS的“標(biāo)記-清理”算法不同扰藕,G1從整體來看是基于“標(biāo)記-整理”來實現(xiàn)的收集器缓苛,從局部(兩個Region之間)上來看是基于“復(fù)制”算法實現(xiàn)的,這兩種算法都意味著G1運作期間不會產(chǎn)生內(nèi)存空間碎片实胸,收集后能夠提供整體的可用內(nèi)存他嫡。
4、可預(yù)測停頓:G1除了追求低停頓之外庐完,還能建立可預(yù)測的停頓時間模型钢属,能讓使用者明確指定在一個長度為M毫秒的時間片段內(nèi),消耗在垃圾收集上的時間不得超過N毫秒门躯。
使用G1收集器時淆党,Java堆的內(nèi)存布局與其他收集器有很大的區(qū)別,它將整個Java堆劃分為多個大小相等的獨立區(qū)域(Region)讶凉,雖然還保留著新生代和老年代的概念染乌,但新生代和老年代不再是物理隔離的了,他們都是一部分Region(不需要連續(xù))的集合懂讯。
G1收集器之所以能夠建立可預(yù)測的停頓時間模型荷憋,是因為它可以有計劃地避免在整個Java對中進(jìn)行全區(qū)域的垃圾收集。G1跟蹤各個Region里面垃圾堆積的價值大泻滞(回收所獲得的空間大小以及回收所需要時間的經(jīng)驗值)勒庄,在后臺維護(hù)一個優(yōu)先列表串前,每次根據(jù)允許的收集時間,優(yōu)先回收價值最大的Region(這也是Garbage-First名稱的由來)实蔽。
G1收集器的運作大致可分為:
1荡碾、初始標(biāo)記:需要停頓,耗時短局装;
2坛吁、并發(fā)標(biāo)記;
3铐尚、最終標(biāo)記:需要停頓拨脉,可并發(fā)執(zhí)行;
4塑径、篩選標(biāo)記女坑;