ZGC采用弱一致性内存模型,通过染色指针、读屏障和多视图内存映射协同实现亚毫秒停顿;它允许短暂视图不一致,但确保每次访问必正确、不丢数据、不读错误中间态。

ZGC 的内存一致性模型不是强一致,而是“弱一致性”——它不保证所有线程在同一时刻看到完全相同、最新更新的对象状态,但通过精心设计的机制,在并发回收过程中仍能保障程序语义正确、不丢数据、不读到错误中间态。
这个模型是 ZGC 实现超低停顿(<1ms)的关键妥协与创新,背后依赖三项核心技术协同工作:染色指针、读屏障、以及多视图内存映射。
弱一致性不是放任乱序,而是有约束的并发可见性
ZGC 允许线程在 GC 运行时继续读写对象,但每次读取对象引用时,必须经过“读屏障”检查。这就像在门口加了一道安检——不是禁止通行,而是确保你拿走的是合法副本。
- 读操作触发读屏障后,会判断该引用是否指向已重定位的对象
- 若是,则自动从转发表(Forwarding Table)中查出新地址,并将本地指针“修复”为新位置(即“自愈式更新”)
- 这个过程对应用代码透明,但保证了后续对该对象的访问始终落到有效内存上
因此,“弱一致”体现在:某个线程可能短暂持有旧地址(未触发读屏障前),但只要它真正去读字段或调用方法,屏障就会介入修正;不同线程可能在极短时间内看到同一对象的“旧视图”或“新视图”,但绝不会看到被释放的内存、重复释放的对象,或处于半移动状态的垃圾。
三色标记与多视图映射支撑语义安全
ZGC 使用三色标记(白/灰/黑)跟踪对象可达性,但标记过程全程并发。为避免漏标,它采用“多视图映射”技术:
- 同一个物理内存页,在虚拟地址空间中可被映射多次(如原地址视图、重定位后视图、标记中视图)
- 染色指针的高18位编码了当前对象所处的视图状态(如 marked0 / marked1 / remapped)
- JVM 根据指针颜色,自动选择正确的页表项访问对应视图,无需修改对象头或同步锁
这就让标记、转移、清理阶段可以重叠执行,而不会因线程间观察不一致导致逻辑错误——比如一个线程刚把对象标记为存活,另一个线程就把它当成垃圾清掉了。
实际影响:对开发者几乎零感知,但需避开两类误用
- ✅ 安全:普通字段读写、方法调用、对象创建全部兼容,无需额外同步或 volatile 修饰
- ⚠️ 注意:直接使用 Unsafe.compareAndSet 或 JNI 直接操作内存地址时,绕过读屏障,可能读到陈旧指针或引发 crash —— 这类操作必须配合 ZGC 提供的屏障 API(如 ZAddress.remap())手动处理
- ❌ 禁止:在读屏障未生效路径(如某些 native 回调、信号处理函数)中缓存 Java 对象原始地址并长期复用
ZGC 的弱一致性模型,本质是在硬件内存模型(x86/ARM 的 relaxed ordering)之上,叠加一层轻量级、细粒度的软件保障层。它不追求“全局瞬间一致”,而追求“每次访问必正确”,用极少的运行时代价,换来了 TB 级堆下稳定亚毫秒级停顿。

















