面试必问:Java 11以后默认收集器的变迁逻辑

作者:袖梨 2026-06-20
Java 11起G1成为默认GC,因其分区回收、停顿可控、避免碎片、并发标记等优势,兼顾吞吐与低延迟;Java 17/21仍默认G1,ZGC/Shenandoah为超低延迟可选方案而非替代。

Java 11 开始,G1(Garbage-First)成为默认垃圾收集器,取代了长期沿用的 Parallel GC。这一变更不是偶然调整,而是围绕低延迟、可预测停顿、大堆适应性等现代应用需求逐步演进的结果。

为什么 G1 能取代 Parallel GC 成为默认?

Parallel GC(吞吐量优先)适合批处理类场景,但停顿时间不可控,堆越大,Full GC 风险越高;而 G1 通过分区(Region)、增量回收、停顿时间目标(-XX:MaxGCPauseMillis)等机制,在保持较高吞吐的同时,显著改善响应稳定性。尤其在 4GB+ 堆、多核服务器环境下,G1 的实际表现更均衡。

  • 支持软实时停顿控制(如设为 200ms,JVM 尽力逼近)
  • 避免内存碎片化(通过复制算法整理存活对象)
  • 能并发标记,减少 STW(Stop-The-World)频次与时长

Java 17/21 中默认收集器有变化吗?

没有。G1 仍是 Java 17(LTS)、Java 21(LTS)的默认 GC。但 JDK 持续优化 G1:Java 10 引入并行 Full GC 回退逻辑;Java 12 简化 G1 的 Mixed GC 触发条件;Java 14 默认启用 ZGC(实验性),Java 21 将 ZGC 转为正式特性——但它仍不替代 G1 作为默认,仅作为超低延迟场景的可选方案。

  • ZGC 和 Shenandoah 适用于毫秒级停顿要求(如金融交易、实时游戏服务)
  • G1 仍是通用性最强、运维最成熟的默认选择
  • 若显式指定 -XX:+UseZGC-XX:+UseShenandoahGC,则覆盖默认行为

面试时如何解释这个“变迁逻辑”?

建议用“问题驱动演进”来组织回答:从 JDK 7–8 的 Parallel/ CMS 并存,到 CMS 被废弃(Java 9 标记弃用、14 移除),本质是因 CMS 无法解决浮动垃圾与并发失败导致的长时间 Full GC;而 G1 统一了分代 + 分区思想,兼顾吞吐与延迟,成为折中且可持续演进的基础架构。

立即学习“Java免费学习笔记(深入)”;

  • 别只背“G1 是默认”,要指出它解决了 CMS 的哪些缺陷(如无内存碎片、可预测停顿)
  • 提一句 ZGC/Shenandoah 是 G1 的补充而非替代,体现技术判断力
  • 可补充:OpenJDK 社区明确表示,未来默认 GC 的切换需满足“零配置下多数应用受益”,目前 G1 仍最符合

实际项目中怎么验证和调优?

启动时加 -Xlog:gc*:file=gc.log:time,tags,level(Java 9+ 统一日志框架),观察是否启用 G1(日志含 G1 字样)、Mixed GC 频率、平均停顿是否接近目标值。常见调优点:

  • 调整 -XX:MaxGCPauseMillis(默认 200ms),过小会导致频繁 GC,过大则失去意义
  • 增大堆时,注意 G1 的初始堆大小(-Xms)建议设为 -Xmx 的 50%~75%,避免动态扩容引发额外开销
  • 若 Mixed GC 过于频繁,可适当增加 -XX:G1HeapWastePercent(默认 5%),放宽回收阈值

相关文章

精彩推荐