CMS收集器整理 @white
- 基本說明:
- 目標:獲取最短回收停頓時間
- 算法:標記-清除算法
- 線程:並發
- 步驟:
- 初始標記:(會STP)
- 標記 GC Roots 能直接關聯到的對象,速度很快
- 並發標記:(耗時最長,且可與用戶線程一起工作)
- 進行 GC Root Tracing 的過程
- 重新標記:(會STP)
- 修正並發標記期間因用戶程序繼續運作而導致標記產生變動的那一部分對象的標記記錄。
- 時間:比初始標記稍長,遠比並發標記時間短。
- 並發清除:(耗時最長,且可與用戶線程一起工作)
- 總體來說:可以看作,CMS的內存回收過程是與用戶線程一起並發執行的。
- 初始標記:(會STP)
- 缺點:
- 1、對CPU資源敏感
- 問題:並發階段雖然用戶線程不停頓,但會占用CPU資源導致用戶線程變慢,吞吐量降低。
- 默認回收線程數:(CPU數量+3)/4。
- 當CPU>4時,並發線程>25%的CPU資源。且隨CPU數量增加而下降。
- 當CPU<4時(假設為2),並發線程>50%的CPU資源,很影響用戶體驗。
- 默認回收線程數:(CPU數量+3)/4。
- 解決:
- (不提倡使用)提供“增量式並發收集器”:並發標記和並發清除階段讓GC線程和用戶線程交替運行,減少GC線程的獨占資源時間。會增長GC時間,但降低用戶影響。
- 問題:並發階段雖然用戶線程不停頓,但會占用CPU資源導致用戶線程變慢,吞吐量降低。
- 2、無法處理浮動垃圾:
- 1、浮動垃圾:進行並發清除時用戶線程運行產生的垃圾。只能在下一次GC時再清理。
- 2、並發清理階段用戶線程運行需要預留空間,老年代沒有填充滿就會進行GC。
- JDK1.5:該GC啟動百分比閾值為68%
- JDK1.6:該GC啟動百分比閾值為92%
- 可通過:-XX:CMSInitiatingOccupancyFraction配置(太高會引發大量問題3)。
- 3、老年代GC如果預留空間不足,會出現“Concurrent Mode Failure”,此時虛擬機會啟動后被預案,臨時啟用 Serial Old 收集器,會導致停頓時間變長。
- 3、基於標記-清除算法:
- 問題:會產生空間碎片。大對象分配會因無法找到連續內存空間而觸發FGC
- 解決:
- +UseCMSCompactAtFullCollection參數:在CMS要進行FGC時開啟內存碎片的合並整理過程。默認開啟。
- 引發問題:內存整理導致停頓時間變長
- -XX:CMSFullGCsBeforeCompaction參數:設置N次不壓縮的FGC后跟着來一次帶壓縮的FGC。默認為0,即每次FGC都進行碎片整理。
- +UseCMSCompactAtFullCollection參數:在CMS要進行FGC時開啟內存碎片的合並整理過程。默認開啟。
- 1、對CPU資源敏感