别再背八股了!面试说清 CMS 回收器,就靠这篇了



"面试官问我 CMS 是什么,我脑子一热,差点说成了'内容管理系统'!"这是我一个做了5年 Java 的朋友最近社招面试的真实经历。从这件事我意识到,CMS(Concurrent Mark Sweep)垃圾回收器,虽然老牌,但在很多面试中依然是重点。所以今天,小米就来讲讲我是怎么"跟 CMS 打交道"的------希望能帮到即将跳槽、社招面试的你。

故事的起点:我和 CMS 的第一次"相遇"

还记得那年我第一次维护一个线上老项目,Tomcat 启动参数里赫然写着:

-XX:+UseConcMarkSweepGC

当时的我一脸懵:"这啥?新玩意儿?"

我去查资料才知道,原来它就是传说中的"低延迟垃圾回收器"------CMS,老年代的明星选手,曾一度是互联网公司争相使用的主流 GC 方案。

而这次,也让我开始正式接触 JVM 内存管理的世界。

CMS 的目标是什么?

CMS,全称是 Concurrent Mark Sweep ,中文叫"并发标记-清除"。顾名思义,它的最大特点就是------尽量减少 STW(Stop The World)时间 ,也就是让垃圾回收这件事尽量不打扰业务线程运行

它的"信仰"是:用户体验优先,延迟比吞吐更重要。

也正因为如此,它被广泛用于对响应时间有要求的 Web 服务类系统,像电商、支付、在线教育等系统中。

CMS 的工作流程(记住这四个阶段)

在我看来,CMS 就像是个不打扰别人的清洁工,它一边让用户用着房间,一边偷偷打扫:

1、初始标记(Initial Mark)

  • 短暂停顿(STW)
  • 标记所有 GC Root 直接关联的对象
  • 非常快,一般几毫秒内完成

2、并发标记(Concurrent Mark)

  • 和应用线程同时进行
  • 遍历整个对象图,找出存活对象

3、重新标记(Remark)

  • 再次暂停(STW)
  • 解决并发标记期间产生的对象变动(比如新引用)
  • 相对耗时,是整个过程的瓶颈之一

4、并发清除(Concurrent Sweep)

  • 清理垃圾对象,回收空间
  • 同样是和用户线程一起进行的

总结一句话:只有初始标记和重新标记两个步骤会暂停应用,其它阶段是"边跑边收"。

我踩过的几个 CMS"大坑"

作为一个在生产环境中维护过 CMS 回收器的人,小米必须给你讲几个"实战坑点"。

  1. 碎片化严重

CMS 是"标记-清除"算法,所以不会像 G1 或 Parallel Old 那样做"压缩"。清理之后留下的是"一个个小碎片"。

这意味着:大对象分配容易失败,即使总内存够,但没有一块连续空间就 GG。

解决方案:加上 -XX:+UseCMSCompactAtFullCollection 参数(默认就是 true),并设定压缩频率 -XX:CMSFullGCsBeforeCompaction=5,让 CMS 每执行几次 Full GC 就顺带整理一次空间。

  1. 并发失败(Concurrent Mode Failure)

这个问题听上去就让人心慌:回收器还没干完活,堆就满了!

这通常发生在 CMS 清理速度赶不上对象增长速度时,JVM 被迫切换为"Stop The World 的 Serial Old"模式,系统就顿了,甚至会出现卡顿报警。

应对方法:

  • 增加老年代大小 -XX:CMSInitiatingOccupancyFraction=75(默认是92)
  • 启用 -XX:+UseCMSInitiatingOccupancyOnly 控制 GC 触发时机
  1. 浮动垃圾(Floating Garbage)

由于 CMS 在并发标记、清理期间,业务线程还在创建新对象,所以这些"新生代对象"在 GC 时根本就没看见。

这些没清理到的对象就叫:浮动垃圾

这就是为什么 CMS 没法做到"完全回收",它需要依靠多次回收才能慢慢清理干净。

再聊聊 CMS 的参数优化

你面试的时候,光说机制还不够,能讲讲调优,就显得你"干过活"。

常见调优参数:

经验值建议:

  • 新生代大小设大一点,避免频繁 Minor GC
  • 老年代使用率到 70~75% 左右就开始 GC
  • 定期触发 Full GC,压碎片(适度使用)

CMS 的退场:被谁取代了?

2017 年 Oracle 宣布:CMS 将在 JDK 9 后被标记为"deprecated"

它的接班人是谁?那就是 G1(Garbage First)

为什么?因为:

  • G1 支持压缩(解决了碎片问题)
  • G1 更智能(自动按 Region 分区)
  • G1 有更短更可控的暂停时间

不过,如果你面试中提到:"虽然 CMS 被 G1 替代,但它依然在很多线上系统中运行,了解它是必要的。"------你绝对是加分项!

面试怎么说 CMS?

来,小米总结一段"答题模板"送你:

CMS 是一种以降低 GC 停顿时间为目标的垃圾回收器,采用标记-清除算法,在初始标记和重新标记阶段会暂停业务线程,其余阶段与业务线程并发执行。适用于对响应时间要求高的场景。缺点是内存碎片化严重、容易出现并发失败。调优时可以设置 CMSInitiatingOccupancyFraction 来提前触发 GC,并定期做 Full GC 以压缩空间。目前 CMS 在 JDK 9 后已被标记为废弃,G1 是其继任者。

简洁、有层次、还带优化经验,一听就是干过的!

建议

如果你还在用 CMS,那一定要:

  • 监控老年代使用率
  • 留意 GC 日志是否出现 Concurrent Mode Failure
  • 考虑是否能升级 G1 或 ZGC(JDK11+)

而如果你准备社招,别光死背概念,要结合故事、项目、场景去说,才能让面试官感受到你的"实战经验"。

END

CMS 是一段经典的 JVM 回忆,也是 Java 调优道路上的"必经之坑"。虽然它已经慢慢退场,但它的机制和思维,依然影响着后来的垃圾回收器设计。

面试,是回顾和总结的好机会。希望今天的这篇文章,能帮你更自信地面对面试中的 JVM 回收问题,也希望你不再被 CMS 的"初始标记"和"重新标记"绕晕啦。

如果你觉得这篇文章有帮助,欢迎点赞、转发 给正在找工作的朋友,也欢迎留言说说你被 CMS"坑"过的经历,我们一起成长!

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号"软件求生",获取更多技术干货!

相关推荐
basketball6163 分钟前
Linux C 进程基本操作
linux·运维·服务器·c语言·后端
ku_code_ku13 分钟前
Django由于数据库版本原因导致数据库迁移失败解决办法
后端·python·django
JavaGuide20 分钟前
感谢数字马力收留,再也不想面试了!!
java·后端
望获linux27 分钟前
【Linux基础知识系列】第五十四篇 - 网络协议基础:TCP/IP
java·linux·服务器·开发语言·架构·操作系统·嵌入式软件
liupenglove32 分钟前
云端【多维度限流】技术方案设计,为服务稳定保驾护航
java·开发语言·网络
37手游后端团队35 分钟前
Eino大模型应用开发框架深入浅出
人工智能·后端
要开心吖ZSH42 分钟前
Spring Cloud LoadBalancer 详解
后端·spring·spring cloud
weixin_419658311 小时前
数据结构之B-树
java·数据结构·b树
minji...1 小时前
数据结构 栈(1)
java·开发语言·数据结构