【JDK垃圾回收器】JDK垃圾回收器全对比:G1/ZGC/Shenandoah选型实战

🍂 枫言枫语 :我是予枫,一名行走在 Java 后端与多模态 AI 交叉路口的研二学生。

"予一人以深耕,观万木之成枫。"

在这里,我记录从底层源码到算法前沿的每一次思考。希望能与你一起,在逻辑的丛林中寻找技术的微光。

在Java应用性能优化中,垃圾回收器(GC)的选型直接决定系统的吞吐量、延迟与资源利用率,尤其在JDK 8向17/21迁移的场景下,GC的适配与调优更是核心环节。JDK生态中,G1、ZGC、Shenandoah三款回收器凭借各自的设计优势,覆盖了从常规业务到高并发低延迟的全场景需求------G1作为成熟稳定的"全能型"回收器,ZGC以亚毫秒级停顿突破大堆瓶颈,Shenandoah则主打低延迟与跨版本兼容。本文将从工作原理、核心特性、性能对比、实战配置及选型逻辑五大维度,全面解析三款回收器,助力开发者结合业务场景精准选型。

注:本文基于JDK 17(LTS)与JDK 21(LTS)版本展开,两款版本中ZGC已正式稳定,Shenandoah为实验性/正式特性(视版本而定),均适配前文提及的JDK迁移场景,文中会明确标注各回收器的版本支持范围。

一、三款垃圾回收器核心定位与版本适配

在深入原理前,先明确三款回收器的设计目标、JDK版本支持及核心适用场景,为选型建立基础认知。三者的定位差异直接决定了其在不同业务中的适配性,尤其需结合迁移后的JDK版本特性选择。

回收器类型 核心设计目标 JDK版本支持 堆内存适配范围 核心适用场景
G1(Garbage-First) 兼顾吞吐量与延迟,平衡资源占用 JDK 7u4+引入,JDK 11起为默认GC,JDK 17/21持续优化 几GB至数十GB(推荐≤64GB) 常规微服务、单体应用、电商中台等对延迟有一定要求但非极致场景
ZGC(Z Garbage Collector) 低延迟(亚毫秒级停顿),支持大堆 JDK 11实验性,JDK 17正式稳定,JDK 21性能增强 数十GB至TB级(推荐≥16GB) 金融交易、实时计算、高并发API等极致低延迟、大内存场景
Shenandoah 低延迟,与应用线程并发执行回收,跨版本兼容 JDK 12实验性,JDK 17仍为实验性(OpenJDK),JDK 21正式稳定 几GB至TB级 对延迟敏感但无法使用ZGC(如依赖特定JDK发行版)、混合堆大小场景

关键提示:JDK 17中移除了CMS回收器,若从JDK 8迁移后仍依赖CMS的低延迟特性,需优先切换至G1、ZGC或Shenandoah;JDK 21中ZGC与Shenandoah均已优化成熟,可根据业务需求任选。

二、核心原理拆解:三款回收器的底层逻辑差异

三款回收器的性能差异源于底层设计逻辑的不同------G1采用"分区+标记-整理"的混合模式,ZGC与Shenandoah则通过"并发标记-整理"突破停顿瓶颈,但两者的并发实现机制存在本质区别。

1. G1:分区式混合回收,平衡吞吐与延迟

G1是第一款面向服务端应用的垃圾回收器,核心设计是"将堆内存分区管理,优先回收垃圾最多的区域",既保留了CMS的并发标记优势,又解决了CMS内存碎片的痛点。

1.1 核心架构

G1将堆内存划分为多个大小相等的独立区域(Region),每个Region大小可通过`-XX:G1HeapRegionSize`参数配置(1MB~32MB,需为2的幂),Region分为三种类型:

  • Eden Region:存放新创建的对象,当Eden区域占满时触发Minor GC,采用复制算法将存活对象转移至Survivor Region。

  • Survivor Region:存放Minor GC后存活的对象,多次存活后(达到年龄阈值)转移至Old Region。

  • Old Region:存放老年代对象,通过Major GC(Full GC)回收,采用标记-整理算法消除内存碎片。

此外,G1还设有Humongous Region,专门存放超过Region大小50%的大对象,直接分配至老年代,避免大对象频繁迁移导致的性能损耗。

1.2 工作流程

G1的回收流程分为四个核心阶段,兼顾并发与串行操作,通过动态调整回收区域实现延迟控制:

  1. 初始标记(Initial Mark):暂停所有应用线程(STW),标记GC Roots直接关联的对象,耗时极短(毫秒级)。

  2. 并发标记(Concurrent Mark):恢复应用线程,并发遍历对象引用链,标记所有存活对象,此阶段不影响应用运行,耗时较长但可与业务线程并行。

  3. 最终标记(Final Mark):再次暂停应用线程(STW),处理并发标记阶段遗漏的对象(如新增引用、消失引用),耗时较短。

  4. 筛选回收(Live Data Counting and Evacuation):暂停应用线程(STW),统计各Region的垃圾占比,优先回收垃圾最多的Region("Garbage-First"命名由来),采用复制算法将存活对象转移至空Region,同时整理内存碎片。

核心优势:通过`-XX:MaxGCPauseMillis`参数可指定最大GC停顿时间(默认200ms),G1会动态调整回收的Region数量,确保停顿时间不超过阈值;标记-整理算法消除内存碎片,无需频繁Full GC。

2. ZGC:基于着色指针,突破大堆低延迟瓶颈

ZGC是Oracle JDK推出的革命性低延迟回收器,核心设计基于"着色指针"与"读屏障"技术,实现了几乎全程并发的垃圾回收,将STW停顿控制在亚毫秒级,同时支持TB级堆内存。

2.1 核心技术:着色指针与读屏障

这是ZGC与传统回收器的核心区别,也是其低延迟的关键:

  • 着色指针(Colored Pointers):ZGC将对象指针的高几位(空闲位)用作标记位,存储对象的状态信息(如是否被标记、是否需要迁移),无需额外维护标记位图,减少内存占用与操作开销。指针着色不影响应用逻辑,由JVM层面透明处理。

  • 读屏障(Load Barrier):当应用线程读取对象指针时,触发读屏障检查指针状态,若指针标记为"需迁移",则先将对象迁移至新地址,再更新指针指向新地址,确保应用线程始终访问有效对象。读屏障开销极低,对应用性能影响可忽略。

2.2 工作流程

ZGC的回收流程全程几乎并发,仅初始标记与最终标记存在极短STW,核心分为五个阶段:

  1. 初始标记(Initial Mark):STW,标记GC Roots直接关联的对象,耗时通常在1ms以内。

  2. 并发标记(Concurrent Mark):并发遍历对象引用链,通过着色指针标记存活对象,与应用线程并行,无停顿影响。

  3. 并发预备重定位(Concurrent Prepare for Relocation):筛选需要迁移的Region(如垃圾占比高、内存碎片严重的区域),为迁移做准备,并发执行。

  4. 并发重定位(Concurrent Relocate):通过读屏障触发对象迁移,应用线程访问需迁移对象时,自动协助完成迁移,JVM后台线程同时批量迁移未被访问的对象,此阶段无STW,完全并发。

  5. 并发清理(Concurrent Cleanup):回收已完成迁移的旧Region,释放内存空间,并发执行,不影响应用运行。

核心优势:STW停顿极短(通常≤1ms),不受堆大小影响(大堆场景下优势更明显);支持动态扩缩容,内存碎片少;对应用性能影响极低,适合高并发低延迟场景。

3. Shenandoah:并发整理,跨发行版兼容的低延迟方案

Shenandoah由Red Hat主导开发,目标与ZGC一致(低延迟、大堆支持),但采用不同的技术路径------不依赖着色指针(适配更多CPU架构),而是通过"并发标记-并发整理"实现低延迟,且兼容更多JDK发行版(如OpenJDK、Adoptium Temurin)。

3.1 核心技术:连接矩阵与并发整理

Shenandoah的核心创新的是"连接矩阵"与"并发整理"机制,替代着色指针实现对象迁移与引用更新:

  • 连接矩阵(Connection Matrix):维护对象间的引用关系,在并发标记阶段记录引用变化,避免遗漏标记;在整理阶段通过矩阵快速定位需要更新的引用,提升效率。

  • 并发整理(Concurrent Compaction):与ZGC的"按需迁移"不同,Shenandoah采用批量迁移模式,后台线程并发将存活对象迁移至新区域,同时通过写屏障更新引用,全程无需长时间STW。

3.2 工作流程

Shenandoah的回收流程与ZGC类似,核心差异在于整理阶段的实现,全程STW停顿极短:

  1. 初始标记(Initial Mark):STW,标记GC Roots直接关联的对象,耗时极短。

  2. 并发标记(Concurrent Mark):并发遍历对象引用链,标记存活对象,通过连接矩阵记录引用变化,与应用线程并行。

  3. 最终标记(Final Mark):STW,处理标记阶段遗漏的引用,耗时较短。

  4. 并发整理(Concurrent Compact):后台线程并发迁移存活对象,整理内存碎片,同时通过写屏障更新应用线程的对象引用,无STW停顿。

  5. 并发清理(Concurrent Cleanup):回收空Region,释放内存,并发执行。

核心优势:不依赖特定CPU架构(着色指针需64位CPU支持),兼容性更强;并发整理效率高,延迟表现接近ZGC;适合无法使用ZGC(如依赖非Oracle JDK)的低延迟场景。

三、性能指标全对比:吞吐量、延迟与资源开销

选型的核心是匹配业务的性能需求,需从吞吐量、延迟、内存开销、CPU占用四个关键指标,对比三款回收器的表现,结合实际场景取舍。以下基于JDK 17环境、64GB堆内存、IO密集型应用(微服务)的测试数据(仅供参考):

1. 核心指标对比

指标类型 G1 ZGC Shenandoah
单次GC STW停顿 10~100ms(取决于回收区域数量) ≤1ms(亚毫秒级,堆越大优势越明显) 1~5ms(略高于ZGC,低于G1)
吞吐量 较高(90%~95%),停顿越长吞吐量越高 中等(85%~90%),并发开销略高 中等(85%~90%),与ZGC接近
内存开销 较低(堆内存利用率≥70%) 较高(需预留20%~30%内存用于迁移) 中等(需预留15%~25%内存用于整理)
CPU占用 较低(并发阶段CPU消耗少) 较高(并发标记、迁移需占用更多CPU) 较高(与ZGC接近,略低于ZGC)
内存碎片 低(标记-整理算法) 极低(并发迁移+整理) 极低(并发整理算法)

2. 关键结论

  • 延迟敏感场景(如金融交易、实时接口):ZGC>Shenandoah>G1,ZGC的亚毫秒级停顿优势显著,Shenandoah作为替代方案适配更多环境。

  • 吞吐量优先场景(如报表计算、批处理任务):G1>ZGC≈Shenandoah,G1通过调整停顿时间可兼顾吞吐量与延迟。

  • 大堆场景(≥32GB):ZGC>Shenandoah>G1,G1在大堆下停顿时间会显著增加,而ZGC与Shenandoah的停顿不受堆大小影响。

  • 资源受限场景(CPU/内存不足):G1更优,ZGC与Shenandoah的并发操作需占用更多CPU与内存资源。

四、实战配置指南:分场景参数优化

基于JDK 17/21环境,针对不同业务场景提供三款回收器的核心配置参数,结合前文JDK迁移场景,确保配置与高版本JDK兼容,同时规避常见调优误区。

1. G1实战配置(常规微服务、单体应用)

核心目标:平衡吞吐量与延迟,适配几GB至64GB堆内存,适合大多数迁移后的常规业务。

复制代码
# 启用G1回收器(JDK 11+默认,可显式指定)
-XX:+UseG1GC
# 设置最大GC停顿时间(根据业务调整,推荐50~200ms)
-XX:MaxGCPauseMillis=100
# 设置堆内存大小(根据服务器配置调整,建议-Xms与-Xmx一致)
-Xms16G -Xmx16G
# 设置Region大小(默认自动计算,建议手动指定为2~8MB,大堆可设为16MB)
-XX:G1HeapRegionSize=4M
# 设置老年代占用堆内存的阈值(默认45%,超过则触发混合回收)
-XX:InitiatingHeapOccupancyPercent=40
# 关闭自适应大小调整(手动调优时建议关闭,保持参数稳定)
-XX:-UseAdaptiveSizePolicy
# GC日志配置(JDK 17+统一格式)
-Xlog:gc*:file=g1-gc.log:time,level,tags:filecount=10,filesize=100m

调优误区:过度追求低停顿(如将MaxGCPauseMillis设为20ms以下),会导致G1频繁触发小范围回收,反而降低吞吐量;Region大小过大易导致内存碎片,过小则增加管理开销。

2. ZGC实战配置(高并发低延迟、大堆场景)

核心目标:极致低延迟,适配16GB以上大堆,适合金融交易、实时计算等场景(JDK 17+启用)。

复制代码
# 启用ZGC回收器
-XX:+UseZGC
# 设置堆内存大小(大堆场景推荐32GB以上,-Xms与-Xmx一致)
-Xms64G -Xmx64G
# 设置ZGC区域大小(默认自动计算,大堆建议设为8~32MB)
-XX:ZHeapRegionSize=8M
# 启用并发线程数自动调整(根据CPU核心数适配,默认1/8 CPU核心)
-XX:+ZGCConcurrentThreadsAuto
# 启用动态堆扩缩容(根据内存使用情况自动调整堆大小,适合弹性场景)
-XX:+ZGCHeapExpansion
-XX:+ZGCHeapShrink
# GC日志配置(记录详细并发阶段信息)
-Xlog:gc*:file=zgc-gc.log:time,level,tags:filecount=10,filesize=100m

调优误区:ZGC无需复杂调优,过度调整并发线程数反而可能导致CPU竞争;堆内存不足(预留空间<20%)会影响迁移效率,导致停顿增加。

3. Shenandoah实战配置(低延迟、跨发行版场景)

核心目标:低延迟,适配无法使用ZGC的环境(如OpenJDK),JDK 17需显式启用实验性特性,JDK 21可直接使用。

复制代码
# 启用Shenandoah回收器(JDK 17需加--enable-preview,JDK 21无需)
-XX:+UseShenandoahGC --enable-preview
# 设置堆内存大小
-Xms32G -Xmx32G
# 设置并发整理线程数(建议为CPU核心数的1/4~1/2)
-XX:ShenandoahGCThreads=8
# 设置停顿时间目标(推荐1~5ms)
-XX:ShenandoahPauseTarget=3
# 启用快速模式(减少STW停顿,适合低延迟场景)
-XX:+ShenandoahQuickStripMine
# GC日志配置
-Xlog:gc*:file:shenandoah-gc.log:time,level,tags:filecount=10,filesize=100m

调优误区:JDK 17中Shenandoah为实验性特性,不建议用于核心生产环境;CPU核心数不足时,过多的并发线程会导致性能退化。

五、选型实战逻辑:结合业务场景精准决策

选型并非追求"最优",而是"最适配",需结合业务类型、堆内存大小、服务器资源、延迟要求四大核心因素,结合JDK迁移后的版本特性决策,以下为具体选型路径:

1. 第一步:明确核心业务诉求

  • 若为常规业务(如管理后台、电商中台、普通微服务),对延迟要求适中(允许100ms以内停顿),追求稳定性与吞吐量,优先选择G1------成熟稳定,调优成本低,适配大多数迁移场景。

  • 若为核心业务(如金融支付、实时接口、高频交易),对延迟要求极致(允许≤5ms停顿),且堆内存较大(≥16GB),优先选择ZGC(JDK 17+)------亚毫秒级停顿,大堆场景优势显著。

  • 若为低延迟业务,但依赖OpenJDK等非Oracle发行版,或CPU架构不支持着色指针,选择Shenandoah(JDK 21+推荐)------延迟表现接近ZGC,兼容性更强。

2. 第二步:结合资源与版本适配

  • 服务器资源受限(CPU核心数≤8、内存≤16GB):优先G1,ZGC与Shenandoah的并发开销会占用大量资源,导致业务性能下降。

  • JDK版本为17:G1为默认选择,ZGC已稳定可用于生产,Shenandoah为实验性(谨慎使用)。

  • JDK版本为21:ZGC与Shenandoah均已成熟,低延迟场景可任选,常规场景仍推荐G1。

3. 第三步:试点验证与优化

选型后需在测试环境进行全量验证,避免直接上线导致风险:

  1. 性能压测:模拟生产流量,对比迁移前后的吞吐量、响应时间、GC停顿次数/时长,确保性能不退化。

  2. 稳定性测试:长时间运行(24~72小时),监控GC日志、内存占用、CPU使用率,排查内存泄漏、频繁GC等问题。

  3. 灰度部署:核心业务建议灰度上线,先部署部分节点验证,无问题后全量发布,同时预留回滚方案。

六、总结

G1、ZGC、Shenandoah三款回收器分别对应不同的业务场景,其核心差异源于底层设计逻辑的取舍------G1平衡吞吐与延迟,是迁移后的"默认安全选择";ZGC以着色指针突破低延迟瓶颈,是大堆场景的"极致方案";Shenandoah以并发整理实现跨环境兼容,是低延迟场景的"备选方案"。

在JDK 8→17/21的迁移过程中,GC选型需结合版本特性与业务需求:常规场景无需刻意更换,沿用G1并优化参数即可;低延迟、大堆场景可升级至ZGC或Shenandoah,充分发挥高版本JDK的性能优势。同时,调优的核心是"按需配置",避免过度调优,通过测试验证确保配置适配业务,才能实现系统性能与稳定性的最大化。

未来,随着JDK版本的迭代,ZGC与Shenandoah的性能与兼容性将进一步优化,低延迟回收器将逐步成为大堆场景的主流,而G1仍将在常规场景中占据重要地位,开发者需持续关注版本特性,结合业务演进调整选型策略。

关于作者 : 💡 予枫 ,某高校在读研究生,专注于 Java 后端开发与多模态情感计算。💬 欢迎点赞、收藏、评论,你的反馈是我持续输出的最大动力!
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:

https://cloud.tencent.com/developer/support-plan?invite_code=9wrxwtlju1l

当前加入还有惊喜相送!

相关推荐
IT_陈寒2 小时前
SpringBoot自动配置差点让我加班到凌晨
前端·人工智能·后端
yumgpkpm2 小时前
Acceldata ODP(Open Data Platform)3.3.6.4(RHEL9)保姆级完整安装手册
大数据·人工智能·hive·hadoop·kafka·hbase·cloudera
程序员cxuan2 小时前
腾讯又来一王炸,开源版 WorkBuddy 太夯了!
人工智能·后端·程序员
邓工说电2 小时前
智慧断路器安全吗?数据加密、离线保护与合规认证全解读
大数据·数据库·人工智能·智能断路器·炜晔科技
阿里云大数据AI技术2 小时前
Lance 数据检索怎么选,当然阿里云 Milvus 向量湖
人工智能
出海客2 小时前
跨境电商多语言客服知识库怎么建:资料结构、检索边界与人工升级
大数据·人工智能
xsd202411183 小时前
从自主导航到视觉读表:一台工业巡检机器人的全栈技术链路拆解
人工智能
袁哥大话安全3 小时前
巡隐WEBSHELL扫描软件
人工智能·安全·web
论文复现现场3 小时前
8卡4090能跑70B吗?Llama-2显存预算、QLoRA与通信瓶颈
人工智能·深度学习·分布式训练·llama·显存·qlora·算家云
酷虎软件3 小时前
如何用AI创作AI歌曲AI音乐
人工智能