中 困难
ZGC特性#
一句话答案#
ZGC 是低延迟 GC,停顿 <10ms 且不随堆增大而增加,核心技术:着色指针 + 读屏障,JDK15 生产就绪。
核心要点
ZGC(Z Garbage Collector):
- JDK 11 实验性引入,JDK 15 正式支持
- 目标:停顿时间 < 10ms,且与堆大小无关(无论 8GB 还是 8TB)
核心技术1:染色指针(Colored Pointers)
普通指针:[0...0][地址](64位,低46位存地址)
ZGC指针: [标记位][地址](利用64位指针的高位存元数据)
标记位(4位):
Finalizable | Remapped | Marked1 | Marked0
是否进入finalize | 是否重映射 | GC标记位 | GC标记位plaintext- 直接在指针上存储 GC 状态信息,不需要额外的位图(Bitmap)
- 好处:GC 状态读取不需要访问对象头,更快
核心技术2:读屏障(Load Barrier)
- 每次读取引用时(Load),JVM 插入一小段检查代码
- 检查指针的染色位,如果发现对象已被移动,立刻更新引用(Self-Healing)
- 好处:GC 可以在并发阶段移动对象,不需要 STW 全量更新引用
- 代价:每次读引用有轻微额外开销(通常 < 5%)
ZGC 的工作流程(几乎全并发):
初始标记 → STW(极短,< 1ms)
并发标记 → 与用户线程并发
再标记 → STW(极短)
并发转移准备 → 并发
初始转移 → STW(极短)
并发转移 → 与用户线程并发(移动对象,读屏障保证安全)plaintextZGC 适用场景: 超大堆(数十GB~TB),对延迟极度敏感(金融交易、实时系统)
面试回答(2分钟版)
ZGC是JDK11引入、JDK15正式生产就绪的低延迟垃圾收集器,它的核心目标是将GC停顿控制在10毫秒以内,而且这个停顿时间不随堆大小增长——无论堆是8GB还是8TB,停顿都一样短。它靠两个核心技术实现:第一是染色指针,利用64位指针的高位存储GC元数据信息,这样读取GC状态不需要访问对象头,效率更高;第二是读屏障,每次加载引用时插入一小段检查代码,如果发现对象已经被GC移动了,就立刻自愈更新引用指向新地址。这样GC在并发转移对象时不需要STW去全量更新引用。ZGC的工作流程几乎全并发,只有初始标记、再标记和初始转移三个极短的STW阶段,每个不到1毫秒。代价是读屏障带来约5%的吞吐开销。适用场景是超大堆加低延迟要求的系统,比如金融交易、实时计算;小堆场景G1可能更合适。
追问与易错
追问方向:
- “ZGC 怎么做到停顿 <10ms?”→ 几乎全并发设计,只有初始标记/再标记/初始转移三个极短 STW 阶段(各 < 1ms);并发转移靠染色指针+读屏障实现对象移动时无需 STW 全量更新引用
- “ZGC 和 G1 怎么选?”→ 堆 < 8GB 且延迟要求不极端用 G1 足够;超大堆(几十 GB~TB)或对延迟极度敏感(< 10ms)选 ZGC;ZGC 有约 5% 吞吐开销需权衡
- “ZGC 有什么缺点?”→ 读屏障带来约 5% 吞吐损耗、不支持 32 位系统、依赖 64 位指针(不支持指针压缩 CompressedOops)、JDK 版本要求高(JDK15+ 生产就绪)
易错点:
- ❌ ZGC 完全没有 STW——初始标记仍有极短 STW
- ❌ 所有场景都用 ZGC——小堆 G1 可能更合适