zgc读屏障是轻量按需触发的检查机制,通过染色指针状态位(如marked0/remapped)快速判断是否需自愈:若为marked0则查转发表并原子更新指针至新地址,remapped或未标记则直接放行,全程对应用透明且零开销。

ZGC 的读屏障不是用来“拦截所有读取”再统一处理,而是轻量、按需触发的检查机制。它真正的作用,是在对象正在被并发转移时,让应用线程在首次访问旧地址的那一刻,自动发现并切换到新地址——这个过程叫“指针自愈”,且对上层代码完全透明。
读屏障如何触发自愈
当应用线程执行类似 obj.field 这样的字段读取操作时,JVM 会在底层插入读屏障逻辑。该逻辑只做一件事:检查当前指针的“颜色”(即高位状态位):
- 如果指针处于 Marked0 或 Marked1 状态,说明对象正被转移中,此时查转发表(forwarding table),拿到新地址,并原子写回给原指针变量
- 如果已是 Remapped 状态,代表转移完成、引用已更新,屏障直接放行,零开销
- 如果未标记(如刚分配的对象),也直接放行,不干预
为什么必须搭配染色指针
单纯加读屏障无法高效判断“要不要处理”,因为 JVM 不可能为每次读取都去查全局转发表——那会带来灾难性性能开销。ZGC 的解法是把元数据塞进指针本身:
一款AI工具,主要用于使用 Codex CLI 进行深度网络搜索,适用于需要多源综合分析的复杂查询。当 `web_search`(Brave)返回结果不足,或用户……时使用,适合需要提升相关任务效率的用户。
- 64 位指针高 4 位复用为状态位(Marked0 / Remapped / Finalizable 等),低 42 位才是真实地址
- 状态位由 GC 线程在标记/转移阶段原子设置,应用线程仅靠位运算就能快速决策,无需访存查表
- 这使得读屏障从“保守全拦截”变成“精准按需拦截”,吞吐量不因此明显下降
自愈带来的并发安全保证
自愈不只是“修一次指针”,它还隐含了内存可见性与一致性保障:
- 首次访问触发重定向后,后续对该指针的所有访问都落在新地址,避免重复检查
- 写操作本身不经过读屏障,但 ZGC 配合写前屏障(Pre-Write Barrier)确保标记阶段不漏标
- 所有屏障操作都带内存屏障(如
store_release),防止指令重排导致其他线程看到中间态
限制与前提条件
这套机制不是通用的,它依赖明确的运行环境约束:
- 必须使用 64 位 JVM,且禁用压缩指针(
-XX:-UseCompressedOops) - 仅支持 Linux x64 平台;Windows 和 macOS 上的 ZGC 在部分 JDK 版本中仍受限或不可用
- 对象转移发生在页(page)粒度,JDK 16 起支持 in-place relocation(同页内转移),进一步减少跨页访问开销










