cms收集器在jdk9中被废弃、jdk14中移除,解决cmf的首选是迁移到g1或zgc;若短期维持cms,需从触发时机、堆布局、并发能力三方面调优,并监控分析cmf根因。

CMS(Concurrent Mark-Sweep)收集器在 JDK 9 中已被标记为废弃,JDK 14 中彻底移除。因此,**解决 CMS 并发模式失败(Concurrent Mode Failure, CMF)的首选方案不是调优 CMS,而是迁移到 G1 或 ZGC 等现代垃圾收集器**。若因历史原因仍需短期维持 CMS,可从触发时机、堆布局和并发能力三方面入手缓解。
理解 CMF 的根本原因
CMF 发生在 CMS 后备回收(Full GC)前的并发标记阶段——老年代空间不足,无法容纳新晋升对象或浮动垃圾,导致 CMS 被迫中断并发流程,退化为 STW 的 Serial Old 收集,严重影响响应时间。
常见诱因包括:
- 老年代碎片化严重,虽有足够空闲容量但无连续大块空间
- 并发标记耗时过长,期间应用持续分配导致老年代快速填满
- 初始标记或重新标记阶段暂停过久,错过安全回收窗口
- 晋升速率远超 CMS 清理速度(如大量中等生命周期对象涌入老年代)
关键调优参数(仅限 CMS 场景)
以下参数需结合监控数据谨慎调整,避免过度压缩吞吐或引发更频繁的 CMF:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- -XX:CMSInitiatingOccupancyFraction=N:设为 60–75(默认约 92),让 CMS 更早启动并发周期。注意:值过低会增加 CPU 开销;过高则易触发 CMF
- -XX:+UseCMSInitiatingOccupancyOnly:禁用 JVM 自动动态调整触发阈值,保证行为可预测
- -XX:CMSMaxAbortablePrecleanTime=5000:延长可中止预清理时间,减少重新标记压力
- -XX:+CMSScavengeBeforeRemark:在重新标记前强制一次 Young GC,降低 remark 阶段扫描量
- -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=1:对 Full GC 后的老年代做压缩(仅限小堆,大堆慎用,停顿极长)
替代方案:平滑迁移至 G1
G1 天然规避 CMF 类问题,通过区域化设计与预测式回收,在可控停顿内完成老年代回收:
- 启用:-XX:+UseG1GC
- 设定目标停顿:-XX:MaxGCPauseMillis=200(根据业务容忍度调整)
- 避免 Full GC:-XX:G1HeapRegionSize=1M(合理设置 Region 大小,避免巨型对象直接进老年代)
- 监控建议:-Xlog:gc*,gc+heap=debug,gccpu(JDK 10+)或 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps(旧版)
迁移前建议用 jstat -gc
长期建议:面向未来选型
JDK 8u282+ 可试用 ZGC(低延迟,TB 级堆友好);JDK 11+ 推荐 ZGC 或 Shenandoah(两者均支持并发压缩,无明显“并发失败”概念)。它们不依赖老年代占用率触发,而是基于分配速率与已用内存动态调度。
若必须保留在 CMS 环境,务必配合 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 持续采集日志,用 GCViewer 或 gceasy.io 分析 CMF 前后老年代使用曲线、Young GC 晋升量及并发阶段耗时,再针对性调整。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










