ZGC 染色指针与读屏障

候选人小张在面试阿里 P7 时,面试官问道:

"ZGC 的染色指针具体是怎么用 64 位指针的?"

小张说:"用了几位来存储颜色..."面试官追问:"那 42 位能表示的最大堆地址是多少?"

小张答不上来...

一、核心问题:染色指针与读屏障 🔴

1.1 问题拆解

第一层:位布局(怎么用?)
  "ZGC 的 64 位指针是怎么划分的?"
  考察点:颜色位 vs 地址位

第二层:读屏障(怎么实现?)
  "ZGC 的读屏障具体做了什么?"
  考察点:指针重映射

1.2 标准回答

P5 级别:64 位指针的划分

ZGC 的 64 位指针布局

graph TD
    P[64 位指针]
    P --> B1[位 0-41<br/>堆地址(低 42 位)]
    P --> B2[位 42<br/>Finalizable 标记]
    P --> B3[位 43<br/>Remapped 标记]
    P --> B4[位 44<br/>Marked1 标记]
    P --> B5[位 45<br/>Marked0 标记]
    P --> B6[位 46-63<br/>保留(用于扩展)]

地址范围

42 位地址可以寻址 4TB(2^42 = 4TB)的堆空间。

P6 级别:读屏障实现

读屏障的检查逻辑

Object read(Object ref) {
    Object obj = ref.get();  // 读取对象引用

    // 读屏障检查
    if (colorOf(ref) == Marked0) {
        // 对象是可达的,直接返回
        return obj;
    } else if (colorOf(ref) == Remapped) {
        // 对象已移动到新地址
        Object newObj = lookup(obj);  // 查找新地址
        ref.update(obj, newObj);      // 更新引用
        return newObj;
    } else {
        // 其他颜色处理
    }
}

【面试官心理】 这道题我能问到 P7 级别,是因为染色指针是 ZGC 的核心创新,涉及到 CPU 架构和操作系统的支持。

二、JDK 15+ 的改进 🟢

2.1 压缩指针支持

JDK 15 之前,ZGC 不支持压缩指针(JDK 8 的 UseCompressedOops)。JDK 15+ 通过 3 个颜色位 + 3 个保留位的方式支持压缩指针。

💡

面试加分点:能说出"JDK 15 中 ZGC 的指针格式使用了 3 个保留位,为未来扩展留下了空间(如支持更多的颜色标记或更细粒度的 GC 状态)",说明他关注了 JDK 的演进。

⚠️

面试陷阱:被问到"染色指针需要操作系统支持吗",很多人会说"不需要"。准确答案是:ZGC 的染色指针利用了 x86 架构的内存标签(Memory Tagging)特性(如果可用),否则 ZGC 使用软件的 Fallback 实现,性能会稍低。