CMS垃圾收集器與G1收集器

1、CMS收集器

  CMS收集器是一種以獲取最短回收停頓時間爲目標的收集器。基於“標記-清除”算法實現,它的運作過程如下:

1)初始標記

2)併發標記

3)重新標記

4)併發清除

  初始標記、從新標記這兩個步驟仍然需要“stop the world”,初始標記僅僅只是標記一下GC Roots能直接關聯到的對象,熟讀很快,併發標記階段就是進行GC Roots Tracing,而重新標記階段則是爲了修正併發標記期間因用戶程序繼續運作而導致標記產生表動的那一部分對象的標記記錄,這個階段的停頓時間一般會比初始標記階段稍長點,但遠比並發標記的時間短。

 640?wx_fmt=png&wxfrom=5&wx_lazy=1

  CMS是一款優秀的收集器,主要優點:併發收集、低停頓。

缺點:

1)CMS收集器對CPU資源非常敏感。在併發階段,它雖然不會導致用戶線程停頓,但是會因爲佔用了一部分線程而導致應用程序變慢,總吞吐量會降低。

2)CMS收集器無法處理浮動垃圾,可能會出現“Concurrent Mode Failure(併發模式故障)”失敗而導致Full GC產生。

浮動垃圾:由於CMS併發清理階段用戶線程還在運行着,伴隨着程序運行自然就會有新的垃圾不斷產生,這部分垃圾出現的標記過程之後,CMS無法在當次收集中處理掉它們,只好留待下一次GC中再清理。這些垃圾就是“浮動垃圾”。

3)CMS是一款“標記--清除”算法實現的收集器,容易出現大量空間碎片。當空間碎片過多,將會給大對象分配帶來很大的麻煩,往往會出現老年代還有很大空間剩餘,但是無法找到足夠大的連續空間來分配當前對象,不得不提前觸發一次Full GC。

2、G1收集器

G1是一款面向服務端應用的垃圾收集器。G1具備如下特點:

1、並行於併發:G1能充分利用CPU、多核環境下的硬件優勢,使用多個CPU(CPU或者CPU核心)來縮短stop-The-World停頓時間。部分其他收集器原本需要停頓Java線程執行的GC動作,G1收集器仍然可以通過併發的方式讓java程序繼續執行。

2、分代收集:雖然G1可以不需要其他收集器配合就能獨立管理整個GC堆,但是還是保留了分代的概念。它能夠採用不同的方式去處理新創建的對象和已經存活了一段時間,熬過多次GC的舊對象以獲取更好的收集效果。

3、空間整合:與CMS的“標記--清理”算法不同,G1從整體來看是基於“標記整理”算法實現的收集器;從局部上來看是基於“複製”算法實現的。

4、可預測的停頓:這是G1相對於CMS的另一個大優勢,降低停頓時間是G1和CMS共同的關注點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度爲M毫秒的時間片段內,

5、G1運作步驟:

1、初始標記;2、併發標記;3、最終標記;4、篩選回收

上面幾個步驟的運作過程和CMS有很多相似之處。初始標記階段僅僅只是標記一下GC Roots能直接關聯到的對象,並且修改TAMS的值,讓下一個階段用戶程序併發運行時,能在正確可用的Region中創建新對象,這一階段需要停頓線程,但是耗時很短,併發標記階段是從GC Root開始對堆中對象進行可達性分析,找出存活的對象,這階段時耗時較長,但可與用戶程序併發執行。而最終標記階段則是爲了修正在併發標記期間因用戶程序繼續運作而導致標記產生變動的那一部分標記記錄,虛擬機將這段時間對象變化記錄在線程Remenbered Set Logs裏面,最終標記階段需要把Remembered Set Logs的數據合併到Remembered Set Logs裏面,最終標記階段需要把Remembered Set Logs的數據合併到Remembered Set中,這一階段需要停頓線程,但是可並行執行。最後在篩選回收階段首先對各個Region的回收價值和成本進行排序,根據用戶所期望的GC停頓時間來制定回收計劃。

640?wx_fmt=png

尾部介紹幾個名詞:

1,並行(Parallel):多個垃圾收集線程並行工作,此時用戶線程處於等待狀態 
2,併發(Concurrent):用戶線程和垃圾收集線程同時執行 
3,吞吐量:運行用戶代碼時間/(運行用戶代碼時間+垃圾回收時間)

面試題:

吞吐量優先和響應優先的垃圾收集器如何選擇?

 

(1) 吞吐量優先的並行收集器 
參數配置: 
1, -Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseParallelGC -XX:ParallelGCThreads=8 
說明:選擇Parallel Scavenge收集器,然後配置多少個線程進行回收,最好與處理器數目相等。

2,-Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseParallelGC -XX:ParallelGCThreads=8 -XX:+UseParallelOldGC 
說明:配置老年代使用Parallel Old

3,-Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseParallelGC -XX:MaxGCPauseMills=100 
說明:設置每次年輕代垃圾回收的最長時間。如何不能滿足,那麼就會調整年輕代大小,滿足這個設置

4,-Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseParallelGC -XX:MaxGCPauseMills=100 -XX:+UseAdaptiveSizePolicy 
說明:並行收集器會自動選擇年輕代區大小和Survivor區的比例。

(2)響應時間優先的併發收集器 
1, -Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseConcMarkSweepGC -XX:+UseParNewGC 
說明:設置老年代的收集器是CMS,年輕代是ParNew

2,-Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection 
說明:首先設置運行多少次GC後對內存空間進行壓縮,整理。同時打開對年老代的壓縮(會影響性能)

spark面試順便問道,Spark Streaming應該選擇何種垃圾收集器?

--driver-java-options和 spark.executor.extraJavaOptions這兩個參數將driver和Executor垃圾回收器設置爲cms,以提高響應速度。

本文參考與網絡,如有侵權請聯繫作者刪除。

http://blog.csdn.net/linhu007/article/details/48897597

http://blog.csdn.net/KilluaZoldyck/article/details/75081875

推薦閱讀:

1,淺析Java中的final關鍵字

2,Java多線程和併發基礎面試問答

3,Java反射機制深入詳解

4,spark調優系列之內存和GC調優

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章