跳到主要内容

ZGC:超低延迟的可扩展垃圾收集器

· 阅读需 9 分钟

什么是ZGC?

ZGC(Z Garbage Collector)是JDK 11中推出的一款低延迟垃圾收集器,在JDK 15中已经成为正式特性。它的设计目标是在保证极低延迟(小于10ms)的同时,能够处理大内存(TB级别)的垃圾回收需求。

ZGC的发展历史

孕育阶段(2015-2017)

  • 2015年:Oracle实验室开始ZGC项目的研发
  • 2016年:提出着色指针(Colored Pointers)概念
  • 2017年:完成核心算法设计和原型实现
  • 2017年末:首次在OpenJDK邮件列表中公布

实验特性阶段(2018-2020)

  • 2018年9月:随JDK 11发布第一个实验版本

    • 仅支持Linux/x64平台
    • 实现基础的并发收集功能
    • 引入了Load Barriers技术
  • 2019年:JDK 12-13期间的重要改进

    • 增加了Mac OS支持
    • 优化了并发标记算法
    • 改进了内存分配器性能
  • 2020年:JDK 14-15的突破

    • 增加Windows平台支持
    • 成为正式特性(JDK 15)
    • 引入了分代收集机制的实验版本

快速发展阶段(2021-2023)

  • 2021年:JDK 16-17的增强

    • 支持JNI弱引用优化
    • 改进了NUMA感知
    • 优化了大对象处理
  • 2022年:JDK 18-19的改进

    • 引入可扩展的线程栈处理
    • 优化了并发引用处理
    • 改进了GC触发时机
  • 2023年:最新发展(JDK 20-21)

    • 正式支持分代收集
    • 进一步降低延迟
    • 提升吞吐量表现

关键技术演进

  1. 着色指针技术的发展

    • 初始设计:42位地址空间
    • 改进:支持47位地址空间
    • 优化:降低内存访问开销
    • 增强:支持压缩指针
  2. 内存布局的演进

    • 最初的固定大小页面
    • 动态页面大小支持
    • 多层级页面管理
    • NUMA优化布局
  3. 并发算法的优化

    • 初代标记-重定位算法
    • 引入读屏障优化
    • 改进并发重映射
    • 优化并发栈扫描

性能演进历程

  1. 停顿时间优化

    • 初始版本:<10ms
    • 优化后:<1ms
    • 当前:亚毫秒级
  2. 吞吐量提升

    • 初始:比G1低30%
    • 改进:接近G1水平
    • 现在:特定场景超越G1
  3. 内存开销优化

    • 降低元数据开销
    • 优化页面管理
    • 改进内存分配策略

应用实践的发展

  1. 试验阶段(2018-2020)

    • 主要用于研究和测试
    • 收集早期用户反馈
    • 解决平台兼容性问题
  2. 推广阶段(2021-2022)

    • 开始在生产环境使用
    • 建立性能基准测试
    • 形成调优最佳实践
  3. 全面应用阶段(2023至今)

    • 大规模生产环境采用
    • 完善监控和诊断工具
    • 建立完整的性能调优体系

ZGC的技术创新

1. 着色指针(Colored Pointers)

  • 利用64位指针的高位存储元数据
  • 支持并发的内存重定位
  • 无需额外的读屏障
  • 快速对象定位和访问

2. 内存布局

  • 动态创建的ZPages
  • 支持大小类的对象分配
  • 2MB、4MB等多种页面大小
  • 支持内存压缩和整理

3. 并发处理

  • 所有操作几乎都是并发的
  • 极短的STW暂停时间
  • 支持NUMA架构
  • 可预测的停顿时间

ZGC的工作流程

1. 标记阶段

初始标记(Initial Mark)

  • 标记所有GC Roots
  • 极短暂的STW暂停

并发标记(Concurrent Mark)

  • 遍历对象图
  • 完全并发执行
  • 使用三色标记算法

再标记(Remark)

  • 处理并发标记遗漏的对象
  • 极短暂的STW暂停

2. 重定位阶段

并发准备(Concurrent Prepare)

  • 选择需要重定位的页面
  • 建立转发表

并发重定位(Concurrent Relocate)

  • 复制存活对象
  • 更新引用关系
  • 完全并发执行

ZGC的核心特性

1. 停顿时间控制

  • 无论堆内存多大,停顿时间都在10ms以内
  • 停顿时间与堆大小、对象数量无关
  • 可预测的GC行为

2. 内存管理

  • 动态的页面分配
  • 智能的内存布局
  • 高效的内存整理
  • 支持内存压缩

3. 可扩展性

  • 支持TB级别的堆内存
  • 对大内存应用友好
  • 适应NUMA架构
  • 支持多核CPU并行处理

ZGC的调优参数

基础参数

-XX:+UseZGC                    // 启用ZGC
-Xmx // 最大堆大小
-Xms // 初始堆大小
-XX:ConcGCThreads=n // 并发线程数
java

高级参数

-XX:ZAllocationSpikeTolerance  // 分配速率容忍度
-XX:ZCollectionInterval // 最小GC间隔时间
-XX:ZFragmentationLimit // 碎片化限制
java

ZGC的最佳实践

1. 内存配置

  • 堆内存大小设置
  • 页面大小选择
  • 并发线程数调整

2. 监控指标

  • GC停顿时间
  • 内存使用情况
  • CPU使用率
  • 分配速率

3. 调优建议

  • 避免频繁的大对象分配
  • 合理设置初始堆大小
  • 监控并发线程负载
  • 注意内存碎片化程度

性能特征

1. 延迟表现

  • 停顿时间通常<1ms
  • 99.9%的停顿时间<10ms
  • 停顿时间稳定可预测

2. 吞吐量

  • 并发标记的CPU开销
  • 对比G1的吞吐量差异
  • 在大内存场景下的优势

3. 内存开销

  • 着色指针的内存开销
  • 页面管理的额外开销
  • 并发处理的内存需求

应用场景

1. 最适合的场景

  • 延迟敏感的应用
  • 大内存服务器
  • 实时交易系统
  • 在线游戏服务器

2. 不太适合的场景

  • 小内存应用
  • 32位系统
  • 对吞吐量要求极高的批处理

与其他收集器的对比

1. 相比G1

  • 更低的停顿时间
  • 更好的大内存处理能力
  • 更高的CPU和内存开销

2. 相比Shenandoah

  • 不同的并发策略
  • 独特的着色指针技术
  • 更低的内存开销

常见问题与解决方案

1. CPU使用率高

  • 原因分析
  • 调优方法
  • 监控指标

2. 内存占用大

  • 原因说明
  • 优化策略
  • 配置建议

3. 性能抖动

  • 问题诊断
  • 解决方案
  • 预防措施

未来展望

1. 技术演进

  • 持续的性能优化
  • 新特性开发
  • 生态系统完善

2. 应用前景

  • 云原生环境
  • 微服务架构
  • 实时计算场景

总结

ZGC通过创新的着色指针技术和完全并发的设计,实现了超低延迟的垃圾收集。它特别适合对延迟敏感的大内存应用,代表了垃圾收集器的未来发展方向。

参考资料

  1. OpenJDK ZGC Wiki
  2. JEP 333: ZGC文档
  3. 《深入理解Java虚拟机》- 周志明
  4. ZGC源码分析文档