concurrent mode failure(cmf)是cms收集器在并发清理时老年代可用连续空间耗尽而退化为serial old执行full gc的现象,本质是内存分配与回收节奏失衡,需调低启动阈值、优化晋升节奏并最终升级至g1等现代收集器。

Concurrent Mode Failure(CMF)不是配置写错了,而是 CMS 收集器在并发清理过程中,老年代的“可用连续空间”被提前耗尽,导致被迫退化为 Serial Old 执行 Full GC。它本质是内存分配节奏和垃圾回收节奏失衡的信号,重点不在堆大小,而在预留缓冲是否跟得上实际压力。
看日志确认是不是 CMF
打开 GC 日志,找这几类关键线索:
- 出现 concurrent mode failure 或 Concurrent Mode Failure 字样(大小写不敏感)
- 紧跟着一行 Full GC (Allocation Failure),且 real 耗时明显偏长(常达数百毫秒)
- CMS 并发阶段中断:比如 CMS-concurrent-mark 或 CMS-concurrent-abortable-preclean 后没走完 cleanup 就跳 Full GC
- 日志里看不到后续的 CMS-concurrent-sweep 或 CMS-concurrent-reset
调低 CMS 启动阈值,留出反应余量
默认 -XX:CMSInitiatingOccupancyFraction 在 JDK7+ 后会动态上调(有时到 75%~80%),等于让 CMS 在“红灯区”才起步。建议显式设为 50 左右,并禁用动态调整:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- -XX:CMSInitiatingOccupancyFraction=50
- -XX:+UseCMSInitiatingOccupancyOnly
配合 jstat -gc
稳住晋升节奏,减少突发冲击
CMF 常由流量高峰、批量任务或缓存加载引发大量对象晋升。可从年轻代入手缓冲:
- 适当增大年轻代:-Xmn 或调小 -XX:NewRatio
- 调大 Survivor 区比例,避免对象因 Survivor 溢出而过早进入老年代:-XX:SurvivorRatio=6(默认常为 8)
- 检查是否有定时任务、JSON 序列化、DEBUG 日志等在 CMS 并发周期内密集生成长生命周期临时对象
长期来看,该考虑升级收集器
CMS 已在 JDK9 中被标记为废弃,JDK14 正式移除。CMF 是其架构固有缺陷(标记-清除不压缩、依赖连续空间)的必然表现:
- 碎片一多,大对象就分不进去,哪怕总空闲够,也会触发 CMF
- G1 用 Region 管理,天然缓解碎片压力;ZGC/Shenandoah 更进一步实现几乎无停顿
- 迁移到 G1 时注意:-XX:InitiatingHeapOccupancyPercent=45 是合理起点,别盲目调高










