作為 JDK 早期主流的低延遲垃圾收集器,CMS(Concurrent Mark Sweep)以「大部分階段並發執行」著稱。本文結合 JDK 8 實際 GC 日誌,從收集器組合、核心設計目標、七大並發/STW 階段流程、日誌字段逐行拆解、對象晉升量計算等維度,帶你徹底看懂 CMS 全生命周期。
2016-08-23T02:23:07.219-0200: 64.322: [GC (Allocation Failure) 64.322: [ParNew: 613404K->68068K(613440K), 0.1020465 secs] 10885349K->10880154K(12514816K), 0.1021309 secs] [Times: user=0.78 sys=0.01, real=0.11 secs]
| 字段 | 含義 |
|---|---|
| 2016-08-23T02:23:07.219-0200 | GC 發生的絕對時間(含時區) |
| 64.322 | 相對 JVM 啟動的秒數 |
| GC | 標識 Minor GC(非 Full GC) |
| Allocation Failure | 觸發原因:年輕代空間不足 |
| ParNew | 年輕代收集器名稱 |
| 613404K->68068K(613440K) | 年輕代收集前/後佔用、總容量 |
| 0.1020465 secs | 年輕代收集耗時(不含最終清理) |
| 10885349K->10880154K(12514816K) | 整堆收集前/後佔用、總容量 |
| 0.1021309 secs | 整個 GC 事件總耗時 |
| Times | user=GC 線程總 CPU 時間;sys=系統調用/等待;real=應用實際停頓時間 |
這說明本次 Minor GC 有大量對象未在年輕代存活,直接晉升至老年代,可能預示著年輕代過小或對象存活率異常。
完整日誌片段:
[GC (CMS Initial Mark) [1 CMS-initial-mark: 10812086K(11901376K)] ...] [CMS-concurrent-mark-start] ... [CMS-concurrent-mark: 0.035/0.035 secs] [CMS-concurrent-preclean-start] ... [CMS-concurrent-preclean: 0.016/0.016 secs] [CMS-concurrent-abortable-preclean-start] ... [CMS-concurrent-abortable-preclean: 0.167/1.074 secs] [GC (CMS Final Remark) [YG occupancy: 387920 K (613440 K)] ...] [CMS-concurrent-sweep-start] ... [CMS-concurrent-sweep: 0.027/0.027 secs] [CMS-concurrent-reset-start] ... [CMS-concurrent-reset: 0.012/0.012 secs]
CMS-initial-mark: 10812086K(11901376K) 老年代佔用/容量;10887844K(12514816K) 整堆佔用/容量。Rescan (parallel) 並行重掃、weak refs processing 處理弱引用、class unloading 卸載類、scrub symbol/string table 清理符號/字符串表。YG occupancy 年輕代佔用、CMS-remark 老年代標記後佔用、11200006K(12514816K) 整堆標記後佔用。-XX:CMSMaxAbortablePrecleanTime、-XX:CMSAbortablePrecleanWaitMillis,或啟用 -XX:+CMSScavengeBeforeRemark 在 Remark 前強制一次 Young GC。Concurrent Mode Failure 退化為 Serial Old。可定期觸發 -XX:+UseCMSCompactAtFullCollection(需 STW)或設置 CMSFullGCsBeforeCompaction。-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintTenuringDistribution -Xloggc:/path/gc.log
CMS 通過「分階段並發 + 兩次極短 STW」實現了低延遲目標,但也帶來了碎片化、CPU 競爭、浮動垃圾等副作用。深度理解七大階段的日誌含義、準確計算晉升量、針對性調優 Preclean/Remark 參數,是駕馭 CMS 的關鍵。隨著 G1、ZGC、Shenandoah 的成熟,新項目建議優先評估新一代低延遲收集器;存量系統若仍在用 CMS,做好日誌監控與碎片整理策略同樣至關重要。