HoRain云--JVM垃圾回收器指南
本文详细对比了Java虚拟机(JVM)中G1、CMS、ZGC和Shenandoah四种主流垃圾回收器的特性。G1适合平衡吞吐量与延迟的场景,CMS(已废弃)追求低延迟但易产生内存碎片,ZGC和Shenandoah则专为极致低延迟设计,适合大内存系统。文章提供了选择指南:小内存可选G1,大内存推荐ZGC/Shenandoah,并强调实际测试的重要性。最后针对不同JDK版本给出了推荐方案,帮助开发者根

🎬 HoRain云小助手:个人主页
🔥 个人专栏: 《Linux 系列教程》《c语言教程》
⛺️生活的理想,就是为了理想的生活!
⛳️ 推荐
前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。
专栏介绍
|
专栏名称 |
专栏介绍 |
|
本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。 |
|
|
本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制! |
|
|
全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。 |
|
|
本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。 |
|
|
本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。 |
|
|
本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等) |
目录
🏎️ CMS (Concurrent Mark-Sweep)

在 Java 虚拟机(JVM)的众多垃圾回收器中做出选择,确实是在为你的应用匹配一位至关重要的“内存管家”。不同的回收器有着截然不同的设计哲学和适用场景。为了让你快速建立整体印象,下面这个表格清晰地对比了 G1、CMS、ZGC 和 Shenandoah 这四款主流回收器的核心特性。
|
特性维度 |
G1 (Garbage-First) |
CMS (Concurrent Mark-Sweep) |
ZGC (Z Garbage Collector) |
Shenandoah |
|---|---|---|---|---|
|
核心目标 |
平衡吞吐量与停顿时间(可预测) |
最小化停顿时间(低延迟) |
极致低延迟(亚毫秒/毫秒级),超大堆 |
极致低延迟,与堆大小无关 |
|
停顿时间 |
通常 10-200 毫秒,可预测 |
停顿时间较短(百毫秒级) |
通常 < 10ms,甚至亚毫秒 |
通常 < 10ms |
|
堆内存支持 |
数GB 到 数百GB(推荐 >6GB) |
数GB 到 几十GB |
数十GB 到 TB级别 |
数十GB 到 TB级别 |
|
压缩/整理 |
疏散式复制(标记-整理算法),局部整理,避免碎片 |
标记-清除,不压缩,易产生内存碎片 |
并发压缩,几乎无停顿 |
并发压缩,几乎无停顿 |
|
JDK 版本 |
JDK 7u4+ 正式支持,JDK 9+ 默认 |
JDK 1.4.1+,JDK 9+ 标记为废弃 |
JDK 11+ 引入,JDK 15+ 生产可用 |
非Oracle JDK(如OpenJDK)提供 |
|
适用场景 |
对延迟有要求但更看重平衡的大多数服务端应用 |
对响应延迟敏感、堆空间不太大的服务端应用 |
对延迟极度敏感、超大堆内存的金融、实时系统 |
与ZGC类似,追求低延迟且JDK版本受限 |
💡 深入理解各回收器特点
🔄 G1 (Garbage-First)
G1 的设计目标是成为一个在全堆操作和停顿时间之间取得良好平衡的收集器。
-
核心机制:它将堆划分为多个固定大小的 Region,并引入 记忆集合(RSet) 来记录跨 Region 的引用。其工作核心是停顿预测模型,允许你通过
-XX:MaxGCPauseMillis参数设定期望的最大停顿时间目标。G1 会据此目标,在每次回收时优先选择回收价值最高(即垃圾最多)的 Region(这就是“Garbage-First”的由来)进行回收,从而在有限时间内获得最大收益。 -
主要回收过程:包括年轻代回收(Young GC)和为混合回收(Mixed GC)做准备的全局并发标记周期。
-
注意事项:G1 需要额外的内存来维护 RSet(通常占堆的 5%-20%),并且维护 RSet 的写屏障会带来一定的运行时开销。
🏎️ CMS (Concurrent Mark-Sweep)
CMS 是 JVM 中早期实现并发垃圾回收的收集器,其主要目标是最小化应用停顿时间。
-
核心机制:采用“标记-清除”算法,其最大的特点是并发收集。只有初始标记和重新标记阶段需要短暂的 STW 停顿,而最耗时的并发标记和并发清除阶段都可以与应用线程一起工作。
-
显著问题:由于使用标记-清除算法,CMS 不进行内存压缩整理,因此随着程序运行,老年代会产生内存碎片。当碎片严重时,可能导致大对象无法分配,从而触发一次耗时的 Full GC。此外,在并发阶段,如果垃圾产生速度超过回收速度,会发生“并发模式失败(Concurrent Mode Failure)”,同样会引发 Full GC。
⚡ ZGC (Z Garbage Collector)
ZGC 是一款革命性的低延迟垃圾收集器,其设计目标是在 TB 级堆内存下,将停顿时间控制在 10 毫秒以内。
-
核心技术:ZGC 几乎所有的 GC 操作(标记、转移/压缩、重定位)都是并发执行的。它通过着色指针(Colored Pointers) 技术在指针上存储元数据,并结合读屏障(Load Barrier) 来实现并发条件下对象状态的追踪和指针的自愈。
-
核心优势:停顿时间与堆大小无关,这意味着即使堆扩展到 TB 级别,应用停顿依然能保持极短且稳定。同时,它通过并发压缩有效避免了内存碎片问题。
-
适用场景:主要面向对延迟有极端要求、堆内存非常大的场景,如金融交易系统、实时数据处理等。
🔄 Shenandoah
Shenandoah 的设计目标与 ZGC 非常相似,也致力于实现低停顿时间和并发压缩。
-
与 ZGC 的异同:两者都实现了并发压缩,但技术路径不同。ZGC 依赖着色指针和读屏障,而 Shenandoah 主要通过 Brooks Pointer 和读屏障 来达成并发转移。一个重要的非技术差异是,Shenandoah 并非 Oracle 官方 JDK 的组成部分,但在 Red Hat 的 OpenJDK 发行版等中提供。
-
适用场景:与 ZGC 高度重合,适用于追求低延迟且堆内存较大的应用。当因 JDK 版本或其他原因无法使用 ZGC 时,Shenandoah 是一个强有力的备选方案。
🧑💻 如何选择垃圾回收器
综合以上分析,你可以遵循以下决策框架进行选择:
-
评估核心需求:
-
延迟优先:如果应用对响应时间极其敏感(如金融交易、在线游戏),要求停顿在 10 毫秒以下,应优先考虑 ZGC 或 Shenandoah。
-
吞吐量与延迟平衡:如果应用对吞吐量也有较高要求,并能接受 100-200 毫秒的可预测停顿,G1 是一个稳健且成熟的选择,特别是从 JDK 9 开始它已是默认回收器。
-
传统或特定场景:对于堆内存不大(如小于 8GB)且延迟不极端的传统应用,传统的 Parallel Scavenge(吞吐量优先)或 CMS(低延迟,但请注意其已被标记为废弃)可能仍有价值,但新项目强烈不推荐使用 CMS。
-
-
考虑堆内存大小:
-
小于 16GB:G1 和 ZGC/Shenandoah 均可,G1 在吞吐量上可能更有优势。
-
16GB - 32GB:G1 仍可胜任,但 ZGC/Shenandoah 的低延迟优势开始显现。
-
大于 32GB:强烈建议选择 ZGC 或 Shenandoah,因为它们的停顿时间几乎不随堆大小增长。
-
-
确认 JDK 版本:
-
JDK 8:选择有限,主要是 CMS 或 G1(G1 在 JDK 8 中已可用,但可能不如后续版本成熟)。
-
JDK 11:G1 是默认选择,ZGC 和 Shenandoah 已可用,但 ZGC 在此版本可能仍为实验性或尚未达到最佳状态。
-
JDK 15+:ZGC 和 Shenandoah 已趋于成熟和生产可用,可以放心评估和使用。
-
-
最重要的建议:测试!
理论分析是起点,但最终决策必须基于实际测试。在你的应用典型负载下,启用 GC 日志,使用监控工具(如 VisualVM, JMC, 或专业的 GC 日志分析工具如 GCeasy)来观察不同回收器的实际表现,包括停顿时间、吞吐量影响、CPU 和内存开销等。
希望这份详细的对比和分析能帮助你为应用找到那位最合适的“内存管家”。如果你能分享更多关于你应用的具体情况,比如预期的堆大小、主要的业务类型、JDK版本以及对延迟和吞吐量的具体要求,我也能提供更具体的建议。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙
更多推荐



所有评论(0)