【Java虛擬機(jī)】 垃圾回收器

了解了Java虛擬機(jī)垃圾回收算法一文中的內(nèi)容,我們來(lái)學(xué)習(xí)它們的具體是實(shí)現(xiàn)——垃圾回收器。
不用的廠商、不同版本的虛擬機(jī)都會(huì)提供不同的垃圾回收器,用戶可以根據(jù)自己的場(chǎng)景需求配置要使用的垃圾回收器。
學(xué)習(xí)垃圾回收器,需要明確一個(gè)思想:沒(méi)有最好的垃圾回收器,只有最合適的。
了解垃圾回收器只為根據(jù)具體的應(yīng)用場(chǎng)景選擇最合適的那一個(gè)。

Serial

Serial回收器是采用復(fù)制算法新生代回收器。
Serial顧名思義,是一個(gè)單線程的回收器。
所謂單線程,指的是在垃圾回收階段,只使用一個(gè)線程去完成。同時(shí)回收過(guò)程會(huì)導(dǎo)致STW(“Stop The Word”)。(暫停其他所有線程,表現(xiàn)為不對(duì)外提供服務(wù))。

STW帶來(lái)的糟糕的用戶體驗(yàn),一直是虛擬機(jī)開發(fā)者努力解決的問(wèn)題??梢哉f(shuō)后續(xù)的回收器都在致力于解決這個(gè)問(wèn)題。

Serial的單線程作業(yè),在當(dāng)前多CPU的環(huán)境下顯得不是很高效。但是單CPU環(huán)境下,Serial相比于其他回收器就會(huì)因?yàn)樗鼪](méi)有線程切換開銷而更加高效。

參數(shù)

-XX:+UseSerialGC:添加該參數(shù)使用Serial進(jìn)行垃圾回收。

ParNew

ParNew,Par表示Parallel并行,即使用多線程進(jìn)行垃圾回收,New表示新生代。
ParNew是Serial的多線程版本,除使用多線程外,其余與Serial一樣,也是使用復(fù)制算法,同時(shí)實(shí)現(xiàn)了也共用了很多代碼。

參數(shù)

-XX:+UseParNewGC:使用ParNew進(jìn)行垃圾回收。
-XX:ParallelGCThreads:指定線程數(shù)量。

Parallel Scavenge

Parallel Scavenge,新生代回收器,使用并行多線程復(fù)制算法回收。

相比于其他回收器,Parallel Scavenge關(guān)注于吞吐量(吞吐量=運(yùn)行用戶代碼時(shí)間/(運(yùn)行用戶代碼時(shí)間+垃圾回收時(shí)間)),
其他回收器關(guān)注的是在垃圾回收階段的用戶線程的停頓時(shí)間。
所以Parallel Scavenge更加適用于后臺(tái)計(jì)算類的場(chǎng)景,其他回收器適用于與用戶交互的場(chǎng)景。

參數(shù)

-XX:MaxGCPauseMillis:最大垃圾回收停頓時(shí)間。設(shè)置過(guò)小,會(huì)導(dǎo)致GC頻繁而降低吞吐量。
-XX:GCTimeRatio:垃圾回收時(shí)間占比,通過(guò)1/(1+N)計(jì)算。
-XX:+UseAdptiveSizePolicy:GC自適應(yīng)調(diào)節(jié)策略,開啟后不需要手動(dòng)設(shè)置細(xì)節(jié)參數(shù)

Serial Old

Serial的老年代版本,單線程回收,采用“標(biāo)記-整理”算法。

主要用于虛擬機(jī)的Client模式下。
在Server模式下,與Parallel Scavenge搭配使用或者作為CMS回收器在發(fā)生Concurrent Mode Failure時(shí)的后備預(yù)案。

Parallel Old

Parallel Scavenge 的老年代版本,使用“標(biāo)記-整理”算法。
Parallel Old 的出現(xiàn)取代了 Parallel Scavenge+Serial Old的組合,Parallel Scavenge+Parallel Old 的組合更大程度的利用的多CPU的硬件環(huán)境。

參數(shù)

-XX:+UseParallelOldGC:使用ParallelOld回收器;

CMS

CMS(Concurrent Mark Sweep)并發(fā)標(biāo)記清理回收器,目標(biāo)是獲取最短回收停頓時(shí)間。適用于與用戶交互高頻的場(chǎng)景。
老年代回收器,使用“標(biāo)記-清除”算法。
所謂并發(fā),指的是垃圾回收線程與用戶線程同時(shí)執(zhí)行(可能交替執(zhí)行,可能處于不同CPU上運(yùn)行)
CMS的并發(fā),并不代表著不會(huì)導(dǎo)致STW。CMS分為4個(gè)步驟:初始標(biāo)記,并發(fā)標(biāo)記,重新標(biāo)記,并發(fā)清除,其中的初始標(biāo)記和重新標(biāo)記仍要STW。

初始標(biāo)記:STW,標(biāo)記GC Roots能關(guān)聯(lián)的對(duì)象。
并發(fā)標(biāo)記:進(jìn)行GC Roots Tracing過(guò)程。用戶程序在運(yùn)行,不保證能標(biāo)記所有對(duì)象。
重新標(biāo)記:STW,修正并發(fā)標(biāo)記期間因程序運(yùn)行到導(dǎo)致變動(dòng)的標(biāo)記對(duì)象。
并發(fā)清理:回收所有死亡對(duì)象。

不足

? CPU敏感型。并發(fā)會(huì)占用CPU資源,導(dǎo)致程序變慢,而CPU的數(shù)量會(huì)進(jìn)一步影響到垃圾的回收與程序的運(yùn)行。
? 浮動(dòng)垃圾無(wú)法處理:浮動(dòng)垃圾即并發(fā)清理階段產(chǎn)生的垃圾,需要等到下一次GC進(jìn)行清理。
? 可能出現(xiàn)Concurrent Mode Failure:浮動(dòng)垃圾的存在,需要預(yù)留空間給程序運(yùn)行。而當(dāng)預(yù)留空間不足時(shí),就會(huì)出現(xiàn)Concurrent Mode Failure。 這時(shí)會(huì)啟用Serial Old,而導(dǎo)致FullGC。
? 內(nèi)存碎片的產(chǎn)生:“標(biāo)記-清理”算法產(chǎn)生了內(nèi)存碎片,會(huì)在分配大對(duì)象時(shí),導(dǎo)致FullGC提前。

參數(shù)

-XX:+UseConcMarkSweepGC:使用CMS收集器,使用該參數(shù)后會(huì)默認(rèn)使用ParNew作為新生代回收器。 -XX:+UseCMSCompactAtFullCollection:在進(jìn)行FullGC時(shí),開啟內(nèi)存碎片整理。 -XX:+CMSFullGCsBeforeCompaction:執(zhí)行一定次數(shù)的內(nèi)存不整理的FullGC后,下一次FullGC會(huì)進(jìn)行內(nèi)存整理。 -XX:CMSInitiatingoccupanyFraction:內(nèi)存使用率的閾值,達(dá)到閾值就進(jìn)行GC。 -XX:ParallelCMSThreads:CMS線程數(shù)量

G1

G1將Java堆劃分為多個(gè)大小相等的region,并在后臺(tái)為每個(gè)region的價(jià)值大小維護(hù)一個(gè)優(yōu)先列表
每次回收時(shí),根據(jù)允許的回收時(shí)間,回收價(jià)值最大的region(garbage-first的由來(lái))。

? G1不在需要與其他回收器結(jié)合來(lái)管理整個(gè)堆。
? G1在概念上還保留著新生代與老年代的概念,但是在物理上已經(jīng)不存在,它們只是不同region的集合。
? 由于回收管理的不在是整個(gè)堆,而是部分region,可以預(yù)測(cè)回收需要的時(shí)間
? G1在整體上基于“標(biāo)記-整理”算法,在region間基于“復(fù)制”算法。不會(huì)存在內(nèi)存碎片。
? 并發(fā)與并行,充分利用多核多CPU環(huán)境,來(lái)降低STW時(shí)間。

初始標(biāo)記:STW,標(biāo)記GC Roots能關(guān)聯(lián)的對(duì)象。
并發(fā)標(biāo)記:進(jìn)行GC Roots Tracing過(guò)程,找出存活對(duì)象。
最終標(biāo)記:STW,修正并發(fā)標(biāo)記期間因程序運(yùn)行到導(dǎo)致變動(dòng)的標(biāo)記對(duì)象。
篩選回收:對(duì)各個(gè)region的價(jià)值進(jìn)行排序,根據(jù)用戶期望的GC停頓時(shí)間進(jìn)行回收。

參數(shù)

-XX:+UseG1GC:使用G1收集器
-XX:InitiatingHeapOccupancyPercent:堆的占用率,當(dāng)達(dá)標(biāo)時(shí),開始并發(fā)標(biāo)記。
-XX:MaxGCPauseMillis:最大的停頓時(shí)間。
-XX:G1HeapRegionSize:設(shè)置region大小。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容