ZGC通过染色指针、多视图内存映射和读屏障协同实现亚毫秒级停顿:染色指针将标记状态编码于指针高位,避免全局标记表;三视图(Marked0/Marked1/Remapped)映射同一物理页,支持原子切换;读屏障在每次对象读取时轻量处理重定位,将引用更新分摊至亿次访问中。

ZGC 能在应用线程持续运行的前提下完成对象整理,核心不靠“暂停配合”,而靠一套协同机制:染色指针 + 多视图内存映射 + 读屏障。它不等待线程停步,而是让线程在访问对象时“顺手”参与回收工作。
染色指针:把标记和状态信息塞进指针本身
ZGC 放弃了传统 GC 在对象头里存标记位的做法,转而把标记状态(如是否已标记、是否正在重定位)直接编码进 64 位指针的高几位(如 18 位)。这意味着:
- 无需额外维护全局标记表,节省内存与同步开销
- 每个指针自带“身份快照”,应用线程读取对象时能立即感知其回收阶段
- 为读屏障触发逻辑提供判断依据——这是并发整理落地的关键前提
三视图内存映射:同一物理内存,三个逻辑视角
ZGC 将同一块物理内存,通过 mmap 映射出三个虚拟地址空间:Marked0、Marked1 和 Remapped。它们始终指向相同物理页,但语义不同:
- Marked0/Marked1:用于并发标记阶段,区分两次标记周期(避免漏标)
- Remapped:整理完成后的新地址视图,所有指针最终应指向这里
- ZGC 通过原子切换元数据(如 TLB 条目或页表项),让新分配/更新统一进入 Remapped 视图
这种设计使对象移动无需修改所有引用——只要调整视图映射,旧指针在 Marked 视图下仍可访问原位置,而新访问自动落到 Remapped 地址。
读屏障:线程访问时的“轻量协作者”
每次应用线程执行对象字段读取(Object.field)时,JVM 插入一段轻量检查逻辑(Load Barrier):
- 若发现该指针指向的对象正处于重定位中(即染色位标识为 relocating),则立即调用
relocate_object() - 该函数会将对象复制到 Remapped 视图下的新位置,并更新当前指针值(写回寄存器或栈帧)
- 整个过程只阻塞单次读操作,耗时纳秒级,远低于毫秒级 STW
这相当于把“更新引用”的工作分摊到亿万次普通读操作中,彻底消除了集中修正引用的停顿需求。
并发整理如何真正落地
整理不是一次性搬完再通知,而是一个渐进式、按需触发的过程:
- ZGC 启动并发重定位后,只选择部分 Region 进行对象迁移
- 未被访问的对象保持原位;一旦被读取,读屏障自动触发搬迁并修正指针
- 已搬迁对象在 Remapped 视图下运行,后续访问无额外开销
- 旧 Marked 视图保留一段时间,确保残留访问仍安全(通过指针染色+屏障兜底)
整个过程没有全局暂停点,也没有“等待所有引用更新完毕”的同步屏障。应用线程始终在线,只是个别读操作多了几条指令——这就是 ZGC 实现 sub-1ms 停顿的底层逻辑。

















