# 44. ZGC 如何做到低延迟?它适用于哪些业务场景?
# 标准答案
ZGC(Z Garbage Collector)通过染色指针(Colored Pointers)+ 读屏障(Load Barrier)+ 并发回收等技术实现低延迟,确保 STW(Stop-The-World)时间通常小于 1ms。它适用于低延迟、高吞吐的业务场景,如金融交易、高并发 Web 服务器、游戏服务器和 AI 计算等。
# 答案解析
ZGC 的低延迟特性主要依赖于以下关键技术:
# 1. 染色指针(Colored Pointers)
传统 GC 需要在外部维护对象的标记状态,而 ZGC 直接在 64 位指针的高位存储对象的 GC 状态,如:
Marked0
/Marked1
:标记阶段使用Remapped
:表示对象是否被转移Finalizable
:标记需要 finalize 的对象
这种方式减少了额外的元数据开销,提高了并发回收的效率。
# 2. 读屏障(Load Barrier)
ZGC 采用 读屏障(Load Barrier) 来拦截对象访问,当访问对象时,ZGC 检测对象是否已移动,并在访问时完成对象转移,从而避免 GC 过程中集中 STW。
这与 G1 的**写屏障(Write Barrier)**不同,G1 依赖写屏障来维护 Remembered Set,而 ZGC 主要在对象读取时进行操作,实现更高的并发性。
# 3. 完全并发回收
传统 GC 在对象移动时必须暂停应用线程,而 ZGC 允许大部分 GC 任务并发执行,仅在以下阶段发生 STW:
- 初始标记(STW,通常 <1ms):标记 GC Roots。
- 并发标记(应用线程正常运行)。
- 并发预备重分配(Relocation):确定需要移动的对象。
- 并发对象转移(与应用线程一起执行)。
- STW 更新引用(<1ms):确保所有指针指向最新对象。
这种回收方式避免了 Full GC 造成的长时间停顿,使得 STW 时间极短(<1ms)。
# 4. 无分代设计(Region-less)
传统 GC(如 G1、CMS)采用分代回收(年轻代 + 老年代),但 ZGC 采用无分代设计,所有对象均在相同的堆区域进行回收,避免了跨代晋升带来的额外开销,减少了 GC 停顿时间。
# 5. 大堆支持(最高 16TB)
由于染色指针技术,ZGC 可以支持 16TB 的超大堆空间,而 G1 受限于 57GB(压缩指针模式)。这使得 ZGC 适用于大数据、AI 计算等超大内存场景。
# ZGC 适用的业务场景
ZGC 主要适用于对 低延迟、超大内存 有严格要求的业务,包括:
- 金融交易系统:如股票撮合、外汇交易,要求毫秒级响应,ZGC 的低 STW 可减少交易延迟。
- 高并发 Web 服务器:如电商、社交媒体,ZGC 确保请求处理不中断,降低 P99 响应时间。
- 游戏服务器:游戏对帧率要求严格,GC 停顿会造成卡顿,ZGC 可提供更流畅的体验。
- AI 和大数据计算:AI 训练通常需要大内存(TB 级),ZGC 通过支持 16TB 堆避免频繁 GC 影响计算效率。
# 深入追问
为什么 ZGC 采用读屏障而不是写屏障?
- 读屏障允许在访问对象时完成对象转移,而写屏障通常需要在对象更新时维护元数据,读屏障的方式更适合并发 GC。
ZGC 是否适用于所有 Java 应用?
- ZGC 适用于低延迟、大堆应用,但由于 GC 线程会占用 CPU 资源,对于 CPU 密集型应用(如高频计算)可能不是最佳选择。
G1 和 ZGC 在 STW 上的根本区别?
- G1 仍然需要在 Root Scanning 和 Mixed GC 期间进行 STW,而 ZGC 的 STW 仅限于极短的标记阶段(通常 <1ms)。
# 相关面试题
- G1、ZGC、Shenandoah 在低延迟场景下的对比?
- 染色指针(Colored Pointers)如何优化 GC?
- 如何选择合适的 GC?不同 GC 的适用场景是什么?