面试记录 2026-10-16
题目:介绍下CMS的垃圾回收过程
难度:medium
标签:jvm/gc, general/knowledge, difficulty/medium
评分:⭐⭐⭐⭐☆(4/5)
我的回答
CMS垃圾回收器已经很少使用了,基本也不推荐使用,现在堆分配内存空间在8到32G的基本就使用G1,在向上的就用ZGC;
CMS更接近一个中间产物,在9的时候已经不用了,jdk14就已经移除了;
CMS期望的是垃圾回收和系统使用一起进行,不发生STW,但目标是好的实现起来就没那么容易了;
CMS是老年代的回收算法,整个回收过程有4个阶段初始标记,会短暂的进行STW,标记一批次重要的对象,然后并行标记,这个阶段不做stw,然后是再次标记,又一次进行stw,最后是垃圾回收,期望是通过分批次的标记,降低gc的stw,但是因为并行执行,会引入很多二次变动的问题,而且CMS使用的是标记清理算法,会产生很多内存碎片,当无法正常通过CMS算法回收后还会退回到单线程的垃圾回收
点评
优点:
- 四阶段讲清楚:初始标记(STW)→ 并发标记 → 重新标记(STW)→ 清理,STW 分布准确
- 局限性认知到位:并发导致引用变动、标记-清除产生碎片、退化到 Serial Old
- GC 器选型认知好:8-32G 用 G1,更大用 ZGC,CMS 已移除(JDK 14)
- 期望 vs 现实:CMS 期望无 STW,但实现有两次 STW
不足:
- 未提 CMS 的触发条件(老年代使用率达阈值,默认 70%)
- 未提 CMS 的写屏障机制(处理并发引用变动)
- 未提 CMS 的碎片化问题会导致提前 FullGC(晋升失败)
- 未提 CMS 的 CPU 占用高(并发标记需要多个线程)
补充:CMS 是并发标记-清除,适合堆 ≤ 8G、停顿敏感的场景。JDK 9+ 废弃,JDK 14 移除。
完整讲解
第一部分:知识重点剖析
核心考点定位:考察对 CMS 四阶段流程、STW 分布、局限性(碎片化/并发问题/退化)的完整理解。
知识点拆解:
- CMS 四阶段流程:
- 初始标记(STW):标记 GC Roots 直接关联的对象,短暂停顿
- 并发标记(并发):从 GC Roots 遍历整个对象图,标记存活对象,与用户线程并发
- 重新标记(STW):处理并发标记期间的引用变动,通过写屏障追踪变动对象,短暂停顿
- 并发清理(并发):清理未被标记的对象,与用户线程并发
- CMS 的 STW 分布:初始标记 + 重新标记 两次 STW,总停顿通常 < 50ms
- CMS 的局限性:
- 并发导致引用变动:并发标记期间用户线程修改引用,需要写屏障追踪
- 标记-清除产生碎片:不移动对象,碎片化导致大对象无法分配,触发 FullGC
- 退化到 Serial Old:并发回收失败(碎片化或回收速度跟不上分配速度),退化到单线程 FullGC
- CPU 占用高:并发标记需要多个线程,默认 (Runtime.getRuntime().availableProcessors() + 3) / 4
- CMS 的触发条件:老年代使用率达阈值(默认 70%,-XX:CMSInitiatingOccupancyFraction)
- CMS 的写屏障:对象引用赋值时插入的检查代码,把被修改对象重新标记为"脏",重新标记阶段扫描这些"脏"对象
- GC 器选型:8-32G 用 G1,> 32G 用 ZGC/Shenandoah,CMS 适合 ≤ 8G、停顿敏感场景
第二部分:考察方向与延伸递进
考察方向:
- 深度:四阶段 STW 分布、写屏障机制、碎片化导致退化
- 广度:与 G1、Parallel Old 的对比
- 应用:CMS 参数调优(-XX:+UseConcMarkSweepGC、-XX:CMSInitiatingOccupancyFraction)
延伸递进面试题:
- CMS 和 G1 有什么区别?
- 解答要点:CMS 是并发标记-清除(有碎片),G1 是 Region 化 + Mixed GC(可预测停顿);CMS 适合 ≤ 8G,G1 适合 8-32G
- CMS 的碎片化问题如何导致 FullGC?
- 解答要点:标记-清除不移动对象,碎片化导致大对象无法分配(空间分配担保失败),触发 FullGC;可通过 -XX:+UseCMSCompactAtFullCollection 触发碎片整理
- 为什么 CMS 在 JDK 14 移除?
- 解答要点:CMS 并发回收失败频繁退化到 FullGC、碎片化问题、维护成本高,G1/ZGC 更优
第三部分:面试者参考回答(三步法口语化,300-400 字)
【一句话结论】
面试官您好,CMS 是并发标记-清除,四阶段(初始标记 STW → 并发标记 → 重新标记 STW → 并发清理),适合 ≤ 8G、停顿敏感场景,JDK 14 已移除。
【三点展开】
第一,CMS 四阶段:初始标记(STW,标记 GC Roots 直接关联对象)、并发标记(并发遍历对象图,标记存活对象)、重新标记(STW,处理并发期间的引用变动,通过写屏障追踪)、并发清理(清理未标记对象)。两次 STW 总停顿通常 < 50ms。
第二,CMS 的局限性:并发导致引用变动需要写屏障追踪、标记-清除不移动对象产生碎片导致大对象无法分配触发 FullGC、并发回收失败退化到 Serial Old(单线程 FullGC)、CPU 占用高(并发标记需要多个线程)。
第三,CMS 的触发条件和参数:老年代使用率达阈值(默认 70%,-XX:CMSInitiatingOccupancyFraction)触发。参数 -XX:+UseConcMarkSweepGC 启用,-XX:+UseCMSCompactAtFullCollection 触发碎片整理。JDK 9 废弃,JDK 14 移除,推荐 G1(8-32G)或 ZGC(> 32G)。
【一句边界】
当然,CMS 适合堆 ≤ 8G、停顿敏感的场景。堆 > 8G 推荐 G1(Region 化 + Mixed GC 可预测停顿),堆 > 32G 推荐 ZGC(STW < 1ms)。CMS 已移除,新项目不应使用。