ZGC实现超低停顿的核心是全程并发执行、着色指针和读屏障协同:着色指针将标记状态编码至指针高位,省去查表开销;读屏障在每次加载引用时轻量检查并自愈;所有GC阶段(标记、转移、重映射)均与用户线程并发,仅初始/最终标记需极短STW。

ZGC 实现超低停顿的核心在于全程并发执行、着色指针(Colored Pointers)和读屏障(Load Barrier)三者协同,避免 Stop-The-World(STW)阶段在大部分回收动作中出现。
着色指针:元信息内嵌到地址本身
ZGC 将对象标记状态(如是否已标记、是否重定位)直接编码进 64 位指针的高几位(Linux/x64 默认用第 57–63 位),无需额外维护标记位数组或卡表。这样,JVM 在访问对象时仅靠检查指针颜色就能快速判断对象状态,省去全局同步查表开销。
- 例如:一个指针高 4 位为 0010 表示该对象已标记但未重定位;0100 表示正在重定位中
- 地址空间预留足够大(通常使用 48 位寻址),保证着色后仍能覆盖实际堆范围
- 着色不改变对象真实地址,只是“语义叠加”,硬件层面完全兼容
读屏障:拦截对象加载,保障并发一致性
ZGC 在每次对象引用加载(即 load 指令)时插入轻量级读屏障。它不是阻塞操作,而是检查指针颜色并按需做少量工作(如转发、自愈),确保应用线程看到的对象始终有效。
- 当发现指针处于“重定位中”状态,读屏障会立即把该引用更新为新地址,并返回新对象——这个过程叫“自愈(self-healing)”
- 读屏障由 JIT 编译器在运行时自动注入,对 Java 代码透明
- 相比 CMS 的写屏障或 G1 的写前屏障,ZGC 的读屏障触发频率更高但单次开销极小,且无锁、无全局竞争
全阶段并发:标记、转移、重映射均与用户线程并行
ZGC 将 GC 周期拆解为多个短小阶段,全部设计为可中断、可分片、可并发执行,STW 仅保留在极短的初始标记(Initial Mark)和最终标记(Final Mark)等几个毫秒级的“染色根”环节。
立即学习“Java免费学习笔记(深入)”;
- 并发标记:从 GC Roots 出发遍历对象图,靠读屏障保证过程中新创建/修改的引用不漏标
- 并发转移(Relocation):选择部分活跃区域进行复制,目标页分配后,通过读屏障驱动引用更新
- 并发重映射(Remap):将所有旧地址统一修正为新地址,同样借助读屏障懒更新,避免一次性扫描整个堆
内存管理优化:大页支持与 NUMA 感知
ZGC 默认启用透明大页(THP)和 NUMA 感知分配,减少 TLB miss 和跨节点内存访问延迟,进一步压缩停顿波动。
- 使用 2MB 大页替代 4KB 页,降低页表项数量和地址转换开销
- 在多插槽服务器上,优先将对象分配到靠近其访问线程所在 CPU 的内存节点
- ZGC 自动适配 Linux 的
membind策略,无需人工配置即可提升局部性


















