G1自JDK 7u4起基于分代设计,ZGC则从JDK 11摒弃分代到JDK 21重拾分代;二者分代目的不同:G1以代际预测驱动回收调度,ZGC以降低并发标记开销为优化补充。

Java GC的分代模型并非一成不变,G1和ZGC各自走出了一条不同的演进路径:G1从诞生起就基于分代设计,而ZGC最初完全放弃分代,直到JDK 21才正式引入分代支持——这标志着两者在“如何组织内存生命周期”这一根本问题上的理念碰撞与融合。
G1:分代是根基,Region是载体
G1自JDK 7u4引入就采用明确的分代结构。它把堆划分为大小相等的Region,每个Region动态归属为Eden、Survivor或Old,甚至Humongous(大对象区)。年轻代收集(Young GC)用复制算法快速清理短命对象;老年代则通过混合收集(Mixed GC)按垃圾密度优先回收部分Old Region,兼顾停顿可控与空间整理。这种“逻辑分代+物理分区”的组合,让它在JDK 9成为默认GC后长期稳居服务端主力地位。
- 年轻代大小由-XX:MaxGCPauseMillis驱动自适应调整,目标是满足停顿约束
- Remembered Set维护跨Region引用,避免全堆扫描,但带来5–10%内存开销
- JDK 21新增-XX:+UseGenerationalG1,进一步优化代际边界识别与混合回收效率
ZGC:从无分代到分代,为低延迟让步
ZGC在JDK 11初版中刻意摒弃分代模型,所有Region统一管理,靠并发标记+颜色指针+读屏障实现极低STW。它的设计哲学是:分代判断本身会引入不确定性停顿,不如全程并发处理更可控。但实际运行发现,大量对象在年轻代就死亡,不加区分地全堆扫描浪费资源。于是JDK 21正式加入分代ZGC(-XX:ZGenerational=1),首次支持Eden/Survivor/Old的逻辑划分,但仍保持Region大小动态可调(2MB/32MB/512MB),且所有阶段仍高度并发。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 启用分代后,ZGC能跳过已知存活率低的区域,减少标记工作量
- 不再依赖Remembered Set,改用着色指针内嵌状态位,内存开销更低
- 初始标记和最终标记STW仍控制在1ms内,其余全部并发执行
关键差异不在“是否分代”,而在“为何分代”
G1的分代是调度策略的核心——它靠代际行为预测回收收益;ZGC的分代是性能优化的补充——它在不牺牲停顿上限的前提下提升并发效率。这意味着:
立即学习“Java免费学习笔记(深入)”;
- 对延迟敏感型系统(如交易、实时风控),ZGC分代开启后仍比G1更稳定,尤其堆超过16GB时
- 对吞吐优先或需精细调优的场景(如批处理、中间件),G1的代际参数(如-XX:G1NewSizePercent)仍提供更强控制力
- 二者都不再有传统意义上的“永久代”或“元空间GC强耦合”,类卸载机制已解耦
分代模型正从“强制范式”转向“可选能力”——G1夯实它,ZGC重构它,而JDK 26的双引擎协同优化,正在让这种选择变得更轻量、更透明。

















