圖解JVM分代垃圾回收流程與算法的選擇
本文來自和你在一起的博客,介紹JVM的分代垃圾回收流程,并比較了不同的垃圾收集算法。
分代垃圾回收流程示意
#p#
選擇合適的垃圾收集算法
串行收集器
用單線程處理所有垃圾回收工作,因為無需多線程交互,所以效率比較高。但是,也無法使用多處理器的優(yōu)勢,所以此收集器適合單處理器機器。當然,此收集器也可以用在小數(shù)據(jù)量(100M左右)情況下的多處理器機器上。可以使用-XX:+UseSerialGC打開。
并行收集器
對年輕代進行并行垃圾回收,因此可以減少垃圾回收時間。一般在多線程多處理器機器上使用。使用-XX:+UseParallelGC.打開。并行收集器在J2SE5.0第六6更新上引入,在Java SE6.0中進行了增強--可以對年老代進行并行收集。如果年老代不使用并發(fā)收集的話,默認是使用單線程進行垃圾回收,因此會制約擴展能力。使用-XX:+UseParallelOldGC打開。
使用-XX:ParallelGCThreads=<N>設(shè)置并行垃圾回收的線程數(shù)。此值可以設(shè)置與機器處理器數(shù)量相等。
此收集器可以進行如下配置:
最大垃圾回收暫停:指定垃圾回收時的最長暫停時間,通過-XX:MaxGCPauseMillis=<N>指定。<N>為毫秒.如果指定了此值的話,堆大小和垃圾回收相關(guān)參數(shù)會進行調(diào)整以達到指定值。設(shè)定此值可能會減少應(yīng)用的吞吐量。
吞吐量:吞吐量為垃圾回收時間與非垃圾回收時間的比值,通過-XX:GCTimeRatio=<N>來設(shè)定,公式為1/(1+N)。例如,-XX:GCTimeRatio=19時,表示5%的時間用于垃圾回收。默認情況為99,即1%的時間用于垃圾回收。
并發(fā)收集器
可以保證大部分工作都并發(fā)進行(應(yīng)用不停止),垃圾回收只暫停很少的時間,此收集器適合對響應(yīng)時間要求比較高的中、大規(guī)模應(yīng)用。使用-XX:+UseConcMarkSweepGC打開。
并發(fā)收集器主要減少年老代的暫停時間,他在應(yīng)用不停止的情況下使用獨立的垃圾回收線程,跟蹤可達對象。在每個年老代垃圾回收周期中,在收集初期并發(fā)收集器 會對整個應(yīng)用進行簡短的暫停,在收集中還會再暫停一次。第二次暫停會比第一次稍長,在此過程中多個線程同時進行垃圾回收工作。
并發(fā)收集器使用處理器換來短暫的停頓時間。在一個N個處理器的系統(tǒng)上,并發(fā)收集部分使用K/N個可用處理器進行回收,一般情況下1<=K<=N/4。
在只有一個處理器的主機上使用并發(fā)收集器,設(shè)置為incremental mode模式也可獲得較短的停頓時間。
浮動垃圾:由于在應(yīng)用運行的同時進行垃圾回收,所以有些垃圾可能在垃圾回收進行完成時產(chǎn)生,這樣就造成了“Floating Garbage”,這些垃圾需要在下次垃圾回收周期時才能回收掉。所以,并發(fā)收集器一般需要20%的預留空間用于這些浮動垃圾。
Concurrent Mode Failure:并發(fā)收集器在應(yīng)用運行時進行收集,所以需要保證堆在垃圾回收的這段時間有足夠的空間供程序使用,否則,垃圾回收還未完成,堆空間先滿了。這種情況下將會發(fā)生“并發(fā)模式失敗”,此時整個應(yīng)用將會暫停,進行垃圾回收。
啟動并發(fā)收集器:因為并發(fā)收集在應(yīng)用運行時進行收集,所以必須保證收集完成之前有足夠的內(nèi)存空間供程序使用,否則會出現(xiàn)“Concurrent Mode Failure”。通過設(shè)置-XX:CMSInitiatingOccupancyFraction=<N>指定還有多少剩余堆時開始執(zhí)行并發(fā)收集
小結(jié)
串行處理器:
#t#--適用情況:數(shù)據(jù)量比較小(100M左右);單處理器下并且對響應(yīng)時間無要求的應(yīng)用。
--缺點:只能用于小型應(yīng)用
并行處理器:
--適用情況:“對吞吐量有高要求”,多CPU、對應(yīng)用響應(yīng)時間無要求的中、大型應(yīng)用。舉例:后臺處理、科學計算。
--缺點:垃圾收集過程中應(yīng)用響應(yīng)時間可能加長
并發(fā)處理器:
--適用情況:“對響應(yīng)時間有高要求”,多CPU、對應(yīng)用響應(yīng)時間有較高要求的中、大型應(yīng)用。舉例:Web服務(wù)器/應(yīng)用服務(wù)器、電信交換、集成開發(fā)環(huán)境。