了解了Java虛擬機垃圾回收算法一文中的內(nèi)容,我們來學習它們的具體是實現(xiàn)——垃圾回收器霍狰。
不用的廠商、不同版本的虛擬機都會提供不同的垃圾回收器
缓待,用戶可以根據(jù)自己的場景需求配置要使用的垃圾回收器蚓耽。
學習垃圾回收器,需要明確一個思想:沒有最好的垃圾回收器旋炒,只有最合適的
步悠。
了解垃圾回收器只為根據(jù)具體的應用場景選擇最合適的那一個。
Serial
Serial回收器是采用復制算法
的新生代
回收器瘫镇。
Serial顧名思義鼎兽,是一個單線程
的回收器答姥。
所謂單線程,指的是在垃圾回收階段谚咬,只使用一個線程去完成鹦付。同時回收過程會導致STW(“Stop The Word”)
。(暫停其他所有線程择卦,表現(xiàn)為不對外提供服務)敲长。
STW帶來的糟糕的用戶體驗,一直是虛擬機開發(fā)者努力解決的問題秉继∑碓耄可以說后續(xù)的回收器都在致力于解決這個問題。
Serial的單線程作業(yè)尚辑,在當前多CPU的環(huán)境下顯得不是很高效辑鲤。但是單CPU環(huán)境下
,Serial相比于其他回收器就會因為它沒有線程切換開銷而更加高效杠茬。
參數(shù)
-XX:+UseSerialGC:添加該參數(shù)使用Serial進行垃圾回收月褥。
ParNew
ParNew,Par表示Parallel并行
瓢喉,即使用多線程進行垃圾回收宁赤,New表示新生代
。
ParNew是Serial的多線程版本
灯荧,除使用多線程外礁击,其余與Serial一樣,也是使用復制算法逗载,同時實現(xiàn)了也共用了很多代碼哆窿。
參數(shù)
-XX:+UseParNewGC:使用ParNew進行垃圾回收。
-XX:ParallelGCThreads:指定線程數(shù)量厉斟。
Parallel Scavenge
Parallel Scavenge挚躯,新生代回收器,使用并行多線程
和復制算法
回收擦秽。
相比于其他回收器码荔,Parallel Scavenge關注于吞吐量
(吞吐量=運行用戶代碼時間/(運行用戶代碼時間+垃圾回收時間)),
其他回收器關注的是在垃圾回收階段的用戶線程的停頓時間
感挥。
所以Parallel Scavenge更加適用于后臺計算類
的場景缩搅,其他回收器適用于與用戶交互的場景。
參數(shù)
-XX:MaxGCPauseMillis:最大垃圾回收停頓時間触幼。設置過小硼瓣,會導致GC頻繁而降低吞吐量。
-XX:GCTimeRatio:垃圾回收時間占比,通過1/(1+N)計算堂鲤。
-XX:+UseAdptiveSizePolicy:GC自適應調(diào)節(jié)策略亿傅,開啟后不需要手動設置細節(jié)參數(shù)
Serial Old
Serial的老年代版本
,單線程回收瘟栖,采用“標記-整理”
算法狮荔。
主要用于虛擬機的Client模式下爷耀。
在Server模式下慧脱,與Parallel Scavenge搭配使用或者作為CMS回收器在發(fā)生Concurrent Mode Failure時的后備預案
镜廉。
Parallel Old
Parallel Scavenge 的老年代版本
,使用“標記-整理”
算法寓涨。
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ā)標記清理回收器,目標是獲取最短回收停頓時間
男摧。適用于與用戶交互高頻的場景蔬墩。
老年代回收器,使用“標記-清除”
算法耗拓。
所謂并發(fā)拇颅,指的是垃圾回收線程與用戶線程同時執(zhí)行(可能交替執(zhí)行,可能處于不同CPU上運行)
乔询。
CMS的并發(fā)樟插,并不代表著不會導致STW。CMS分為4個步驟:初始標記竿刁,并發(fā)標記黄锤,重新標記,并發(fā)清除食拜,其中的初始標記和重新標記仍要STW
鸵熟。
初始標記:STW,標記GC Roots能關聯(lián)的對象负甸。
并發(fā)標記:進行GC Roots Tracing過程流强。用戶程序在運行,不保證能標記所有對象呻待。
重新標記:STW打月,修正并發(fā)標記期間因程序運行到導致變動的標記對象。
并發(fā)清理:回收所有死亡對象蚕捉。
不足
? CPU敏感型奏篙。并發(fā)會占用CPU資源,導致程序變慢鱼冀,而CPU的數(shù)量會進一步影響到垃圾的回收與程序的運行报破。
? 浮動垃圾無法處理:浮動垃圾即并發(fā)清理階段產(chǎn)生的垃圾悠就,需要等到下一次GC進行清理。
? 可能出現(xiàn)Concurrent Mode Failure:浮動垃圾的存在充易,需要預留空間給程序運行梗脾。而當預留空間不足時,就會出現(xiàn)Concurrent Mode Failure
盹靴。 這時會啟用Serial Old炸茧,而導致FullGC。
? 內(nèi)存碎片的產(chǎn)生:“標記-清理”算法產(chǎn)生了內(nèi)存碎片稿静,會在分配大對象時梭冠,導致FullGC提前。
參數(shù)
-XX:+UseConcMarkSweepGC:使用CMS收集器改备,使用該參數(shù)后會默認使用ParNew作為新生代回收器控漠。 -XX:+UseCMSCompactAtFullCollection:在進行FullGC時,開啟內(nèi)存碎片整理悬钳。 -XX:+CMSFullGCsBeforeCompaction:執(zhí)行一定次數(shù)的內(nèi)存不整理的FullGC后盐捷,下一次FullGC會進行內(nèi)存整理。 -XX:CMSInitiatingoccupanyFraction:內(nèi)存使用率的閾值默勾,達到閾值就進行GC碉渡。 -XX:ParallelCMSThreads:CMS線程數(shù)量
G1
G1將Java堆劃分為多個大小相等的region
,并在后臺為每個region的價值大小
維護一個優(yōu)先列表
母剥。
每次回收時滞诺,根據(jù)允許的回收時間,回收價值最大的region(garbage-first的由來)
环疼。
? G1不在需要與其他回收器結合
來管理整個堆习霹。
? G1在概念上還保留著新生代與老年代的概念
,但是在物理上已經(jīng)不存在炫隶,它們只是不同region的集合序愚。
? 由于回收管理的不在是整個堆,而是部分region等限,可以預測回收需要的時間
爸吮。
? G1在整體上基于“標記-整理”算法,在region間基于“復制”算法望门。不會存在內(nèi)存碎片
形娇。
? 并發(fā)與并行
,充分利用多核多CPU環(huán)境筹误,來降低STW時間桐早。
初始標記:STW,標記GC Roots能關聯(lián)的對象。
并發(fā)標記:進行GC Roots Tracing過程哄酝,找出存活對象友存。
最終標記:STW,修正并發(fā)標記期間因程序運行到導致變動的標記對象陶衅。
篩選回收:對各個region的價值進行排序屡立,根據(jù)用戶期望的GC停頓時間進行回收。
參數(shù)
-XX:+UseG1GC:使用G1收集器
-XX:InitiatingHeapOccupancyPercent:堆的占用率搀军,當達標時膨俐,開始并發(fā)標記。
-XX:MaxGCPauseMillis:最大的停頓時間罩句。
-XX:G1HeapRegionSize:設置region大小焚刺。