zgc染色指针将marked0、marked1、remapped、finalizable四类元数据编码进64位指针高42–45位空闲比特,实现地址与状态合一;高位可用因x86-64 linux仅用低42–48位寻址,高比特恒为0,不参与物理寻址。

ZGC 的彩色指针不是在对象头或额外结构里存状态,而是把元数据直接“塞进”64位指针的高位空闲比特中——地址和状态合二为一,零内存开销。
为什么高位能用?
现代 x86-64 Linux 系统实际只用虚拟地址的低 42–48 位(对应 4TB–256TB 地址空间),高十几位恒为 0。ZGC 挑出其中连续 4 位(典型是第 42–45 位)作为元数据域,这些位不参与物理寻址,也不影响地址有效性。
- JDK 15+ 默认使用 42 位地址空间,地址掩码为 (1ULL
- 元数据掩码为 0xFULL (即 4 位左移至第 42 位起)
- 真实地址必须用 ptr & Z_ADDRESS_MASK 提取,不能右移——避免符号扩展或非对齐访问错误
四个颜色位分别代表什么?
这 4 位不是随意编码,每种组合对应 GC 生命周期中的明确语义:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- Marked0 / Marked1:交替用于并发标记,解决 ABA 问题;一轮用 Marked0,下轮切 Marked1,防止状态误判
- Remapped:表示该指针指向重定位后的新地址;旧引用未更新时,靠此位触发读屏障跳转
- Finalizable:标识对象含 finalize() 方法,需加入终结队列,由专用线程处理
如何安全提取地址和状态?
所有操作必须无内存访问、无函数调用、无条件分支——这是亚毫秒停顿的前提:
- 地址提取:addr = ptr & Z_ADDRESS_MASK
- 状态提取:color = ptr & Z_METADATA_MASK
- 判断是否已重映射:(ptr & REMAPPED) != 0,结果可直接用于后续跳转逻辑
它和传统标记方式的根本区别
传统 GC 把标记写进对象头或独立 bitmap,每次读对象都要多一次内存访问;ZGC 把标记“随身携带”在指针上,只要拿到指针,状态就已确定:
- 无需访问对象本身即可判定其 GC 阶段
- 极大减少缓存污染和内存带宽压力
- 绕开了对象头写屏障同步开销,也省去了维护外部标记结构的成本
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










