Java 中的 CMS 和 G1 垃圾收集器如何维持并发的正确性?
Java 中的 CMS 和 G1 垃圾收集器如何维持并发的正确性?
CMS(Concurrent Mark-Sweep)和 G1(Garbage-First)垃圾收集器是两种低延迟的垃圾回收器,它们通过并发阶段与应用线程(Mutator)同时运行,以减少暂停时间。为了维持并发垃圾回收的正确性,二者采取了不同的技术和策略。
1. CMS 垃圾收集器的并发正确性维护
1.1 基本工作原理
CMS 使用“标记-清除”算法,主要阶段包括:
- 初始标记(STW):标记 GC Roots。
- 并发标记:从 GC Roots 开始,遍历对象图,标记所有可达对象。
- 重新标记(STW):处理并发标记过程中新产生的引用变化。
- 并发清理:清理未标记的垃圾对象。
1.2 并发正确性维护方法
-
写屏障(Write Barrier):
- 在 Mutator 修改引用关系时,记录修改到一个“卡表”(Card Table)或“脏卡”列表。
- 确保并发标记阶段的新引用可以被重新标记阶段捕获。
-
增量更新(Incremental Update):
- Mutator 在标记阶段修改了指向未标记对象的引用,CMS 会将新创建的引用加入到待标记队列。
-
Stop-The-World 重新标记:
- 通过短暂停顿扫描卡表中的脏卡,捕获并发标记期间可能遗漏的引用变化,确保标记阶段的准确性。
2. G1 垃圾收集器的并发正确性维护
2.1 基本工作原理
G1 使用“标记-整理”算法,将堆分为多个固定大小的分区(Region),垃圾回收按分区优先级进行。主要阶段包括:
- 初始标记(STW):标记 GC Roots。
- 并发标记:从 GC Roots 遍历对象图,标记可达对象。
- 最终标记(STW):处理并发标记阶段的引用变化。
- 清理与整理:回收垃圾对象,并压缩分区。
2.2 并发正确性维护方法
-
SATB(Snapshot-At-The-Beginning):
- G1 使用 SATB 技术维持并发标记的正确性。
- 在标记开始时,记录 Mutator 的对象状态快照,而不是跟踪所有引用的变化。
- Mutator 如果删除了对象的引用,被删除的对象仍会被视为可达,从而保证并发标记阶段不遗漏。
-
写屏障(Write Barrier):
- 在对象的引用发生变化时,通过写屏障将旧引用添加到 SATB 的缓冲区中。
- 确保即使 Mutator 修改了对象图,回收器仍能完整标记。
-
最终标记(Final Remark):
- 在并发标记结束后,通过短暂停顿处理 SATB 缓冲区中的变更记录,确保标记结果一致。
3. CMS 和 G1 在并发正确性上的比较
特性 | CMS | G1 |
---|---|---|
算法 | 标记-清除 | 标记-整理 |
引用变化的处理 | 增量更新(Incremental Update) | 快照集(SATB) |
写屏障 | 修改引用时记录脏卡 | 修改引用时记录旧引用 |
额外的 STW 停顿 | 重新标记阶段 | 最终标记阶段 |
并发标记的正确性保障 | 卡表记录脏区域,重新扫描 | SATB 缓冲区记录引用变化 |
实现复杂性 | 相对较低 | 较高 |
4. 总结
- CMS通过增量更新和卡表记录引用变化,使用重新标记阶段来确保并发标记的正确性。它更简单,但会有内存碎片和“Concurrent Mode Failure”问题。
- G1通过 SATB 快照机制记录标记起点的状态,结合最终标记阶段的补充处理,确保并发标记的准确性。G1 的实现更复杂,但其分区化设计和整理过程能够有效减少内存碎片,适合大堆和低延迟场景。
分类:
Java / JVM
, 面试题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
2022-12-11 1827. 最少操作使数组递增