Java基础、中级、高级、架构面试资料

熬了 15 年!Serial GC 退位,JDK 27 终于让 G1 GC 一统江湖

JAVA herman 17浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领
【腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云

打工人的苦,只有打工人懂。同时,职场中的牛马要上位,更是要忍受苦中苦。

和职场一样,G1 GC 熬了 15 年,才能在 JDK 27 中上位了,G1 GC 终于一统江湖了,Serial GC 彻底让位了。

根据 JEP 523 的信息,G1 GC 在 JDK 27 中成为所有环境的默认 GC,而不再局限于服务器环境。这个“迟到”的默认化历经了约 15 年的演进。15 年间,JDK 换了一茬又一茬,G1 GC 进化了再进化,终于成了默认首选。接下来,我就扯一扯 G1 GC 这一路走来的辛酸泪。

G1 GC 的发展阶段

下面这个表格,是 G1 GC 的一个大致发展时间线。

时期JDK 版本关键里程碑
实验阶段JDK 6u14 (2009)首次作为体验版(Experimental)引入
正式发布JDK 7u4 (2011)正式成为官方支持的 GC,定位服务端、多核、大内存
继续打磨JDK 8 (2014)Parallel GC 依然是服务端的默认霸主,G1 在后台默默打磨,修复各种内存泄漏和性能瓶颈
默认化第一步JDK 9 (2017, JEP 248)成为服务器环境的默认 GC,但小内存/单核环境仍回退到 Serial GC
持续优化JDK 10~JDK 26Full GC 改为并行执行(JDK 10);JDK 14 增强 NUMA 感知,再到 JDK 26 的 JEP 522 通过减少同步开销大幅提升吞吐量。这个过程还伴随着并发标记优化;ZGC/Shenandoah 崛起形成竞争
终极默认化JDK 27 (JEP 523)成为所有环境的默认 GC,彻底取代 Serial GC 在小内存/单核场景的地位

核心演进逻辑

G1 的设计初衷是取代 CMS,解决其“内存碎片”和“不可控停顿”问题。它采用物理分区、逻辑分代的 Region 模型,通过 Mixed GC 和停顿预测模型(Pause Time Goal)来平衡吞吐与延迟。

但早期 G1 在小内存(<< 1792MB)或单核环境下,相比 Serial GC 存在明显劣势。

  • 内存占用高:Remembered Set(RSet)等元数据结构额外消耗 10%-20% 堆内存
  • 吞吐量低:并发标记和写屏障带来额外 CPU 开销
  • 启动慢:复杂的分区初始化逻辑

因此 JDK 9 默认化时做了妥协,JVM 在检测到“受限环境”时自动回退到 Serial GC。

为什么迟到了这么多年?

G1 从 JDK 7u4 发布到 JDK 27 全面默认化,间隔约 15 年。这其中延迟的核心原因是工程上的“不可能三角”,即在吞吐、延迟、内存占用之间难以同时达标。

Oracle 官方在 JEP 523 的动机中明确表示,现在的 G1 已经“脱胎换骨”,足以在所有场景下替代 Serial。

  • 吞吐量追平:得益于 JDK 26 中 JEP 522 对写屏障同步的优化,G1 的最大吞吐量已经逼近 Serial GC。
  • 内存占用大幅瘦身:经过近几个版本的持续优化,G1 的原生内存使用量已经降低到了与 Serial GC 相当的水平。
  • 延迟依然碾压:G1 通过增量回收(Incremental)老年代内存,避免了 Serial GC 动辄整个堆的 Full GC,因此最大延迟表现始终优于 Serial。

另外,还有一个隐含的原因官方未说,那就是现在大内存越来越多。更何况,既然 G1 现在各项指标都能打,且能让 JVM 的行为更加统一(开发者再也不用去猜“我的容器到底默认用了哪个 GC”),Serial 的退位自然是水到渠成。

文章配图参见 https://mp.weixin.qq.com/s/F_bNStJRD7Zo_kiSZKLHRg

小内存场景

在小内存场景,Serial GC 优势长时间以来都难以撼动。

Serial GC 虽然停顿时间长,但在小堆(<< 1GB)和单核环境下。

  • 零并发开销:没有并发标记线程,不抢 CPU
  • 内存极简:无需 RSet、Card Table 等复杂结构
  • 吞吐极高:STW 期间应用线程完全暂停,GC 独占 CPU

现在,JEP 523 明确指出,直到近期 JDK 版本通过减少同步开销(JEP 522)降低原生内存使用,G1 的吞吐量才接近 Serial(注意,这里是接近),内存占用才与之相当。

并发收集器的竞争倒逼 G1 进化

ZGC(JDK 11)和 Shenandoah(OpenJDK 12)的崛起,迫使 G1 必须持续优化。

  • ZGC 承诺 <10ms 停顿,但早期不支持分代、内存开销大(+15-30%)
  • Shenandoah 低延迟但长期实验性,直到 JDK 25 才 finalized

于是,G1 以来了一些关键改进,主要包括下面两点。

  • Remembered Set 内存削减 62%(64GB 堆上从 2GB 降至 0.75GB)
  • Mixed GC 区域选择优化,减少停顿尖刺

这些改进让 G1 终于能在受限环境中与 Serial GC 打平。

保守的默认策略

Oracle/OpenJDK 对“默认 GC”的变更极其谨慎。默认 GC 影响数百万应用,任何性能回退都会引发大规模生产事故。JDK 9 的“服务器环境默认化”本身就是一次渐进式试验,观察了 8 年才敢推进到全环境。

G1 GC 现存的缺点与潜在替代者

尽管成为默认 GC,G1 并非完美。其短板和替代者的定位我整理汇总如下。

G1 的核心缺点

见下面这个表格。

缺点具体表现影响场景
STW 停顿仍存在典型 20-200ms,大堆最坏可达 500ms金融交易、实时系统、p999 敏感型微服务
CPU 开销较高写屏障(Write Barrier)和并发标记持续消耗 CPUCPU 饱和的批处理、嵌入式设备
内存开销即使 JDK 25 优化后,RSet 仍占显著内存容器/K8s 小内存 Pod(<<4GB)
调优复杂度Region 大小、CSet 选择、IHOP 阈值等参数需经验缺乏专职运维的小团队
Full GC 兜底极端情况下退化为串行 Full GC,停顿剧增内存泄漏、突发流量

替代者 ZGC 与 Shenandoah

2026 年的 GC 格局已形成“三足鼎立”之势,见下面这个对比表格。

维度G1ZGC (Generational)Shenandoah (Generational)
停顿时间20-200ms 典型0.1-0.5ms 典型,<<1ms 最坏1-5ms 典型,~10ms 偶发
内存开销基准 (~10% headroom)+15-30%(无压缩指针)+10-20%(支持压缩指针)
吞吐量基准(最高)5-15% 低于 G15-10% 低于 G1
最佳堆范围4GB – 32GB32GB - 多 TB8GB – 64GB
适用场景通用、批处理、ETLHFT、实时系统、超大堆K8s 微服务、中等堆、内存受限

未来演进方向

通过上面的表格可以看出,G1 GC 也面临这其它 GC 给它带来的压力。但是,根据历史 GC 的迭代来看,短时间内 G1 GC 不会很快被 ZGC 等取代。

未来 GC 的演进方向,依旧可能是围绕下面这些场景和需求、特点展开。

  1. G1 不会被立即取代:它仍是“通用场景”的最优解,JDK 25 的改进使其在 4-32GB 堆范围内极具竞争力
  2. ZGC 继续蚕食超大堆市场:分代 ZGC(JDK 21+)已解决不分代的吞吐问题,TB 级堆的低延迟场景几乎必选 ZGC
  3. Shenandoah 的崛起:在 OpenJDK 生态中,Shenandoah 因支持压缩指针(Compressed Oops),内存效率优于 ZGC,适合 K8s 环境
  4. 下一代 GC 的可能性:Lilliput 项目(压缩对象头)和 Valhalla 项目(值类型)可能彻底改变 GC 的内存模型,届时可能出现全新收集器

总结

G1 GC 的“迟到”本质上是 Java 工程保守主义的胜利。它用了 15 年时间证明自己能在所有场景下至少不劣于 Serial GC。JEP 523 的落地消除了 JVM 行为的一个重大不确定性,即我到底用的是哪个 GC?,但默认不等于最优

  • 如果你的应用运行在 <<4GB 容器 且对延迟不敏感,G1 是省心之选
  • 如果需要 p999 < 10ms 的极致延迟,应显式切换至 ZGC
  • 如果在 OpenJDK + K8s 环境追求低延迟与内存平衡,Shenandoah 值得评估

正如 JEP 523 所言,“禁止未来变更默认 GC”并非其目标,随着应用特征和收集器性能演变,默认 GC 应被重新评估 。G1 的全面默认化,或许只是下一个 GC 时代来临前的“过渡仪式”。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » 熬了 15 年!Serial GC 退位,JDK 27 终于让 G1 GC 一统江湖