拆解 CMS/G1/ZGC 三种垃圾回收器算法过程
🔍 一、CMS(Concurrent Mark Sweep)垃圾收集器
✅ 目标:
低延迟(Low Pause),适合对响应时间要求高的应用(如 Web 服务)
⚙️ 使用的算法:
-
新生代:复制算法
-
老年代:标记 - 清除算法
🔁 GC 执行过程:
阶段 | 类型 | 说明 |
---|---|---|
1. 初始标记(Initial Mark) | STW | 标记 GC Roots 直接可达对象,速度快 |
2. 并发标记(Concurrent Mark) | 并发 | 跟踪 GC Roots 的引用链,找出存活对象 |
3. 预清理(Preclean) | 并发 | 处理 Minor GC 期间产生的对象变化 |
4. 重新标记(Remark) | STW | 再次暂停,修正并发标记阶段遗漏的数据 |
5. 并发清除(Concurrent Sweep) | 并发 | 清理不可达对象,释放内存 |
6. 重置(Reset) | 并发 | 重新准备数据结构 |
⚠️ 缺点:
-
无法整理内存,可能出现碎片
-
需要暂停两次(Initial Mark 和 Remark)
-
线程并发期间,会影响吞吐量
面试答题:
CMS 是一种以低停顿为目标的垃圾收集器,采用标记-清除算法进行老年代回收。它通过初始标记、并发标记、重新标记和并发清除阶段完成回收,优点是大部分时间与应用线程并发运行,适合对响应延迟敏感的系统。但缺点是内存碎片问题严重,容易导致 Full GC 频繁发生。
🧩 二、G1(Garbage First)垃圾收集器
✅ 目标:
高吞吐 + 可预测低延迟,JDK 9+ 默认垃圾收集器
⚙️ 使用的算法:
-
新生代:复制
-
老年代:标记-整理
-
全区:Region + 分代 + 指令式分区压缩
🔁 GC 执行过程(按区 Region 回收):
阶段 | 类型 | 说明 |
---|---|---|
1. 初始标记(Initial Mark) | STW | 标记 GC Roots,顺便触发 Minor GC |
2. 并发标记(Concurrent Mark) | 并发 | 从 GC Roots 开始找存活对象 |
3. 最终标记(Remark) | STW | 使用 SATB 算法,修正标记结果 |
4. 筛选回收(Cleanup) | STW/并发 | 根据各 Region 的垃圾比例,优先清除“回收价值最大”的 Region |
💡 G1 特点:
-
将堆划分为多个 Region(而非新老代)
-
根据 Region 的回收价值排序,优先清除「收益最高」的部分
-
支持并发标记 + 并发整理(压缩)
-
默认启用
-XX:+UseG1GC
面试答题:
G1 是面向服务端的大堆优化收集器,通过将堆划分为若干 Region,实现局部收集与全堆管理结合。G1 回收过程包含初始标记、并发标记、最终标记和筛选回收四个阶段,能够同时满足高吞吐和低停顿的需求,是当前最推荐的垃圾回收器之一。
🌈 三、ZGC(Z Garbage Collector)
✅ 目标:
超低延迟(Pause < 10ms),支持大堆内存(最高 16TB)
⚙️ 使用的算法:
-
并发标记 + 并发重分配(无 STW 整理)
-
所有阶段几乎都 并发进行
-
使用染色指针、load barriers
🔁 GC 执行阶段:
阶段 | 类型 | 说明 |
---|---|---|
1. 并发标记(Concurrent Mark Start) | 并发 | 从 GC Roots 出发标记对象 |
2. 并发准备重分配 | 并发 | 计算对象移动后的地址 |
3. 并发重分配(Relocation) | 并发 | 对象移动,引用自动指向新位置 |
✔️ 所有暂停时间 < 1ms,真正实现“几乎无感” GC |
技术亮点:
-
染色指针:将对象头指针作为 GC 元数据容器(空间压缩技巧)
-
Load Barrier:解决对象移动时访问同步的问题
-
几乎100% 并发,最大限度减少 STW
面试答题:
ZGC 是面向大内存与低延迟场景的现代垃圾回收器,其全部回收阶段几乎都并发执行,仅在少量场景进行毫秒级暂停。它使用染色指针与 Load Barrier 技术,无需停顿即可移动对象,彻底解决了传统收集器在大堆与高并发下的性能瓶颈。
📊 四、G1 vs CMS vs ZGC 总结对比
特性/收集器 | CMS | G1 | ZGC |
---|---|---|---|
回收算法 | 标记-清除 | 分区复制 + 整理 | 并发标记 + 并发整理 |
碎片问题 | 有 | 无(整理) | 无 |
停顿时间 | 两次 STW,较短 | 可预测 STW(低) | 极低(<10ms) |
吞吐率 | 高 | 中高 | 高 |
并发能力 | 中 | 强 | 极强 |
是否移动对象 | 否 | 是 | 是 |
适合场景 | 延迟敏感 | 大堆、平衡场景 | 超低延迟、大内存 |
✅五、 CMS 与 G1 在回收策略上的关键区别:是否“评估回收收益”
特性 | CMS(Concurrent Mark Sweep) | G1(Garbage First) |
---|---|---|
内存结构 | 明确的新生代 + 老年代 | 全堆划分为等大小 Region(含 Eden/Survivor/Old) |
回收算法 | 标记 - 清除(老年代) 复制(新生代) | Region 内并行复制 + 并发标记 + 并发整理 |
回收粒度 | 整体老年代 | 分区 Region 级别(可选高性价比的回收区) |
是否评估“收益” | ❌ 否:只做全量或阈值触发回收 | ✅ 是:回收前计算各 Region 的回收收益 = 垃圾量 / 回收成本,优先清除性价比最高的 |
清理效果 | 不整理内存,可能有碎片 | 自动整理 Region,几乎无碎片 |
停顿控制 | 停顿短,但不可控 | 停顿可预测、可配置(如目标 200ms) |
回收目标 | 最小停顿(响应快) | 响应+吞吐平衡、最大性价比 |
🧠 六、JVM垃圾回收器 你可以这样答面试官(组合型模板)
JVM 提供了多种垃圾回收器,适用于不同场景:
CMS 使用标记-清除算法,低延迟但易碎片;
G1 是 JDK 默认收集器,划分 Region,结合分代管理和按需回收,实现较好的吞吐与停顿平衡;
ZGC 则是超低延迟收集器,所有阶段几乎并发执行,最大暂停低于 10ms,适用于金融、电商等延迟敏感系统。
🧠七 、CMS 和 G1区别 可以这样答面试题:
CMS 和 G1 都是以低延迟为目标的收集器。CMS 采用“标记-清除”算法进行老年代回收,虽然并发执行减少了停顿,但因为不整理内存,容易产生碎片,Full GC 风险较高。而 G1 将堆划分为多个 Region,通过计算每个 Region 的“回收收益”来确定回收优先级,优先清除性价比最高的部分,实现可预测、可配置的低延迟回收。相比 CMS,G1 更智能且对大堆支持更好。