在 Java 的垃圾回收(GC)技术演进中,G1(Garbage-First)曾是面向服务器端应用的重要里程碑,但 ZGC(Z Garbage Collector)的诞生标志着低延迟和大内存管理能力的又一次飞跃。
1.设计目标:从「可控停顿」到「极致低延迟」
G1 的局限性
G1 的核心目标是提供 可预测的停顿时间(通过 -XX:MaxGCPauseMillis 参数控制),但这一目标在大堆内存(如 TB 级别)场景下面临挑战
- 堆内存越大,标记和整理阶段耗时线性增长,导致实际 STW(Stop-The-World)时间可能超过预期。
- 分代模型(Eden/Survivor/Old)虽优化了对象生命周期管理,但复杂的内存分区和跨代引用增加了回收开销。
ZGC 的突破ZGC 直接将设计目标锁定为 10ms 以内的停顿时间,且无论堆内存大小如何,STW 时间几乎恒定。其核心理念是
- 完全并发:除初始标记外,所有阶段(标记、转移、重定位)均与应用线程并发执行。
- 无分代设计:取消传统分代,通过动态分区(Small/Medium/Large Region)灵活管理对象,降低内存碎片化风险。
2.核心技术:ZGC 的三大杀手锏
染色指针(Colored Pointers)
原理:在 64 位指针中嵌入 4 位元数据(如标记状态、内存视图),将 GC 信息存储在指针而非对象头中。
优势
- 减少内存访问次数,避免传统 GC 遍历对象头的性能损耗。
- 支持并发标记和转移,无需 STW 阶段即可完成内存整理。
对比 G1:G1 依赖对象头存储标记信息,导致标记阶段需多次访问对象,且内存碎片问题需依赖 STW 整理。
内存多重映射(Memory Multi-Mapping)
原理:将同一物理内存映射到 Marked0、Marked1、Remapped 三个虚拟内存视图,通过视图切换实现并发内存整理。
优势
- 对象转移仅需修改指针视图,无需复制实际数据,大幅降低延迟。
- 支持 TB 级堆内存的高效管理,突破 G1 的堆容量限制。
对比 G1:G1 的 Region 固定大小且需手动调整,大对象(Humongous Region)分配易导致内存碎片。
并发内存压缩(Concurrent Compaction)
原理:通过增量式并发转移,将存活对象逐步迁移到新 Region,同时更新引用关系。
优势
- 避免 G1 的 Mixed GC 阶段因堆增长导致的 STW 时间波动。
- 内存碎片率趋近于零,无需 Full GC 即可维持堆的连续性。
对比 G1:G1 的筛选回收阶段需 STW 整理 Region,且碎片问题可能触发 Full GC。
3.性能表现:ZGC 的实战优势
指标 | G1(默认配置) | ZGC(优化配置) |
最大堆内存 | 支持到 32GB(推荐) | 支持到 16TB |
平均 STW 时间 | 100ms~500ms(TB 级堆) | <1ms(与堆大小无关) |
CPU 开销 | 较低 | 较高(需额外 15% 资源) |
适用场景 | 中小型堆、可控延迟 | 超大堆、极低延迟 |
典型场景对比
- G1:某电商后台系统(堆内存 16GB)通过 -XX:MaxGCPauseMillis=200 实现 200ms 内的停顿,但突发流量时偶发 500ms+ 延迟。
- ZGC:某金融交易系统(堆内存 128GB)启用 ZGC 后,GC 停顿稳定在 1ms 以内,99.99% 请求延迟低于 10ms。
4.调优实践:如何最大化 ZGC 性能
基础参数配置(JDK 17+ 示例)
内存预热
- 启用 -XX:+AlwaysPreTouch 避免运行时内存分配抖动。
监控指标
- 关注 jvm.gc.pause(STW 时间)、jvm.gc.allocation.rate(分配速率)等指标,动态调整线程数。
5.未来展望:ZGC 的进化方向
分代 ZGC(JDK 21+):引入分代模型,降低年轻代回收开销。
跨平台支持:逐步扩展对 Windows 和 ARM 架构的支持。
默认 GC 候选:随着低延迟需求增长,ZGC 或取代 G1 成为 JDK 默认回收器。
6.小结
ZGC 通过染色指针、内存多重映射等创新技术,解决了 G1 在大堆和低延迟场景的瓶颈,成为实时系统、云原生应用的理想选择。尽管其 CPU 开销略高,但随着硬件性能提升和分代 ZGC 的成熟,这一差距正逐步缩小。对于开发者而言,掌握 ZGC 的核心原理与调优技巧,是构建高性能 Java 应用的必经之路。