首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

CMS 垃圾回收器深度剖析:六大階段流程、Card Table 機制、三大缺陷與調優參數

     編輯:Java 綜合教學

CMS 垃圾回收器深度剖析:六大階段流程、Card Table 機制、三大缺陷與調優參數

CMS(Concurrent Mark Sweep)以獲取最短停頓時間為目標,採用「並發標記-清除」算法。本文詳細剖析六大階段、預清理與 Card Table 協作機制、三大痛點及調優參數。

六大執行階段

  1. 初始標記:STW,標記 GC Roots 直接關聯對象。
  2. 並發標記:與用戶線程並發,GC Roots Tracing 標記所有可達對象。
  3. 並發預清理:並發,標記新生代晉升、老年代新分配、並發階段被修改的對象(Card Table)。
  4. 重標記:STW,多線程並行掃描(Rescan),修正並發階段變化。
  5. 並發清理:並發,清理不可達對象。
  6. 重置:清理內部狀態,準備下次 GC。

預清理關鍵機制

觸發 Minor GC 減少重標記壓力

  • 參數 CMSScheduleRemarkEdenSizeThreshold (默認 2MB) + CMSScheduleRemarkEdenPenetration (50%):Eden 佔用超閾值啟動可中斷預清理,達 50% 或 CMSMaxAbortablePrecleanTime (5s) 中斷進入重標記。
  • 若期間發生 Minor GC,新生代存活對象少,重標記 Rescan 只需掃描少量對象,並行效率高(預清理階段已將新生代分塊)。
  • 參數 CMSScavengeBeforeRemark:強制重標記前執行 Minor GC,利弊權衡。

Card Table 處理老年代引用變化

  • 老年代劃分 512B 塊,Card Table 數組每項對應一塊,標記 dirty card。
  • 並發標記階段若對象引用變更,對應 Card 標記 dirty。
  • 預清理掃描 dirty card,標記新可達對象,清除 dirty 標記。
  • 同樣用於 Minor GC 快速識別老年代引用新生代對象(<1% 場景)。

三大缺陷與應對

總結

CMS 通過並發階段極大縮短 STW,犧牲 CPU 吞吐量換取低延遲。調優核心在於根據應用分配速率設置觸發閾值、啟用壓縮、監控浮動垃圾比例。JDK 9+ 標記 CMS deprecated,推薦遷移至 G1/ZGC。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
缺陷原因參數/方案
CPU 佔用高GC 線程與用戶線程搶佔 CPU,默認線程數 (CPU+3)/4CPU≥4 可接受;CPU<4 可用增量模式 (i-CMS),但已 deprecated
浮動垃圾並發清理階段用戶線程產生新垃圾,本輪無法清理CMSInitiatingOccupancyFraction (默認 92%) 提前觸發;動態預測機制
空間碎片標記-清除不整理,大對象無法分配觸發 Full GCUseCMSCompactAtFullCollection (默認開啟) Full GC 時壓縮;CMSFullGCsBeforeCompaction 控制頻率