总结
CMS(Concurrent Mark Sweep)是Java的并发低停顿垃圾回收器,通过“初始标记-并发标记-重新标记-并发清除”四阶段实现,减少停顿时间。缺点包括内存碎片、浮动垃圾问题,且无法处理并发失败。已在JDK9被标记废弃,JDK14正式移除。
详细解析
CMS(Concurrent Mark Sweep)垃圾回收器 是 JVM 中一种以 低延迟 为目标的垃圾回收器,主要用于老年代的垃圾回收。它通过 并发标记-清除算法 减少垃圾回收时的停顿时间(STW),适合对响应速度敏感的应用(如 Web 服务、实时系统)。以下是其核心原理、工作流程及优缺点的详细说明:
一、CMS 的核心设计目标
- 最小化 STW(Stop-The-World)时间:通过并发执行大部分回收阶段,减少用户线程的停顿。
- 适用场景:适合内存较大、对延迟敏感的老年代回收(JDK 9 后已不推荐使用,逐渐被 G1、ZGC 等替代)。
二、CMS 的工作流程
CMS 的回收过程分为 四个阶段,其中 初始标记 和 重新标记 需要 STW,其他阶段与用户线程并发执行:
阶段 | 行为 | 是否 STW |
---|---|---|
1. 初始标记(Initial Mark) | 标记 GC Roots 直接关联 的对象(速度极快)。 | 是 |
2. 并发标记(Concurrent Mark) | 从 GC Roots 出发,遍历老年代 所有存活对象(与用户线程并发执行)。 | 否 |
3. 重新标记(Remark) | 修正并发标记阶段 因用户线程运行导致的标记变动(增量更新或原始快照)。 | 是 |
4. 并发清除(Concurrent Sweep) | 清除未被标记的垃圾对象(与用户线程并发执行)。 | 否 |
三、CMS 的优缺点
优点
- 低延迟:大部分阶段与用户线程并发执行,STW 时间短。
- 适用大内存:适合老年代较大的堆内存(如 4GB 以上)。
缺点
- 内存碎片:使用标记-清除算法,不整理内存,可能导致 Full GC 时触发压缩(STW 时间长)。
- CPU 敏感:并发阶段占用 CPU 资源,可能影响应用吞吐量。
- 浮动垃圾:并发清理阶段用户线程可能产生新垃圾,需预留空间(通过-XX:CMSInitiatingOccupancyFraction设置触发阈值)。
- 并发失败(Concurrent Mode Failure):若回收速度跟不上对象分配速度,会退化为 Serial Old 收集器(Full GC)。
四、CMS 的关键参数
参数 | 作用 |
---|---|
-XX:+UseConcMarkSweepGC | 启用 CMS 收集器。 |
-XX:CMSInitiatingOccupancyFraction=N | 设置老年代使用率达到 N% 时触发 CMS 回收(默认 68%)。 |
-XX:+UseCMSCompactAtFullCollection | Full GC 时压缩内存碎片(默认启用)。 |
-XX:CMSFullGCsBeforeCompaction=N | 执行 N 次 Full GC 后触发内存压缩(默认 0,每次 Full GC 都压缩)。 |
-XX:+CMSClassUnloadingEnabled | 启用类卸载(默认禁用,需显式开启)。 |
五、CMS 的适用场景与局限性
适用场景
- 老年代回收,且应用对延迟敏感(如响应时间要求 < 1s)。
- JDK 1.8 及之前版本(JDK 9 后标记为废弃,JDK 14 中移除)。
局限性
- 内存碎片问题:需配置压缩参数,但会增加 Full GC 时间。
- 并发失败风险:需合理设置触发阈值和堆大小。
- 替代方案推荐:在 JDK 8+ 中,优先使用 G1 或 ZGC(更低延迟、无碎片)。
六、CMS 的完整回收流程图
1 2 3 4 5 6 7 8 9 10 11 |
|
七、CMS 的替代方案
收集器 | 特点 |
---|---|
G1 | 分区回收、可预测停顿、兼顾吞吐与延迟(JDK 9+ 默认)。 |
ZGC | 亚毫秒级延迟、支持 TB 级堆内存(JDK 15+ 生产可用)。 |
Shenandoah | 低延迟、与 ZGC 竞争(需特定 JDK 版本支持)。 |