ZGC染色指针将元数据位(Marked0/1、Remapped、Finalizable)直接编码在64位指针高4位,利用42位有效地址空间剩余高位存储状态,无需额外内存;通过虚拟内存多重映射实现地址别名切换,读屏障检测颜色位触发自愈,完成并发重映射。

染色指针的元数据位不是“存在某处”,而是直接编码在指针值本身
ZGC 的染色指针(Colored Pointers)不依赖额外内存存储元数据,比如对象头、卡表或独立元数据区。它把状态信息(如 Marked0、Marked1、Remapped、Finalizable)直接编码进 64 位指针的高位——确切地说,是**高 4 位(bit 63–60)用于核心颜色标识**,其余高位(共 22 位)保留扩展空间。这些位不是“指向”某个元数据结构,而是指针值的一部分。CPU 加载该指针时,寄存器中自然就包含了地址 + 状态,无需查表、无需解引用、无需缓存同步。
物理映射依托虚拟内存的多重映射(Multi-Mapping)机制
ZGC 利用操作系统(Linux/x86-64)的虚拟内存管理能力,在同一块物理内存页上建立三组不同的虚拟地址视图:
-
Remapped 视图:例如映射到
0x0000000000000000起始的 4TB 范围,对应“稳定地址”,此时指针高 4 位为0001 -
Marked0 视图:映射到
0x1000000000000000,同物理页但不同虚拟地址,指针高 4 位为1000 -
Marked1 视图:映射到
0x0100000000000000,同样指向相同物理页,指针高 4 位为0100
这三组映射共享底层物理帧,因此修改指针的“颜色位”,实质是切换访问该物理内存所用的虚拟地址别名。操作系统页表完成地址翻译,硬件 TLB 自动适配。用户线程读取对象时,CPU 按当前指针值直接寻址,加载屏障仅需检查高 4 位是否为 Marked 状态,决定是否触发重映射逻辑——整个过程无锁、无全局状态依赖。
为什么能安全复用高位?地址空间实际只用 42 位
x86-64 架构虽支持 64 位寻址,但主流 Linux 内核限制用户态虚拟地址空间为 48 位(256TB),ZGC 进一步收缩至 **42 位(4TB)有效地址空间**,即只使用低 42 位表达对象真实位置。剩余的高 22 位(bit 42–63)在常规寻址中恒为 0,对 MMU 来说属于“可忽略前缀”。ZGC 正是利用这部分闲置位,将元数据作为“地址修饰符”嵌入其中。只要保证所有合法 ZAddress 的低 42 位落在已映射的物理页范围内,高位颜色变化就不会导致页错误或越界访问。
着色指针的“自愈性”来自地址与状态的一体化设计
当对象被重定位(Relocate)后,ZGC 不需要遍历所有引用去更新它们。它只需在原地址写入一个转发指针(forwarding pointer),并把所有指向原地址的指针统一设为 Marked 状态。下一次用户线程通过该指针读取对象时,加载屏障检测到 Marked 位,立即从原地址取出转发指针,将其高 4 位改为 Remapped,再返回给线程——这个动作称为“自愈(self-healing)”。整个过程发生在单次访存路径中,且仅影响本次访问的指针副本,其他未触发的引用仍保持 Marked 状态,后续按需修复。这种延迟更新机制,是实现并发重映射的关键物理基础。

















