Java屏障技术不保证业务一致性,而是通过写屏障防止并发标记漏标、读屏障支持ZGC指针自愈,并协同OopMap与安全点保障对象移动时引用安全。

Java 屏障技术(主要是写屏障和读屏障)在垃圾回收中不直接“保证业务一致性”,而是为并发标记与对象移动等关键阶段提供内存访问层面的安全保障,确保可达性分析结果正确、引用关系不被破坏。
写屏障:防止并发标记漏标
当用户线程与GC线程并发运行时,若一个已标记为黑色的对象新增了对白色对象的引用(比如 obj.field = newWhiteObj),就可能造成漏标——该白色对象本应存活却被回收。写屏障在每次字段赋值前或后插入检查逻辑:
- 发现黑→白的新引用,立即将目标白对象重新标记为灰色,加入待扫描队列
- G1 使用原始快照(SATB)方式:在标记开始前记录所有当前引用快照,之后只拦截被修改的引用,避免遍历全堆
- CMS 使用增量更新(IU):在写操作发生时立即把新引用加入标记队列
读屏障:支撑ZGC等超低延迟收集器
ZGC 在对象加载(load)时插入读屏障,用于检测并修正指针状态。它依赖着色指针(Colored Pointers)将对象元信息(如是否已重定位、是否正在标记)编码进引用本身:
- 当线程读取一个对象引用时,读屏障自动判断该指针是否指向已移动位置
- 若指向旧地址,则触发“自愈”(self-healing):原子地将该引用更新为新地址,并同步修正其他持有该引用的地方
- 整个过程对应用线程透明,无需STW,也无需额外维护OopMap或安全点停顿
屏障与安全点、OopMap协同保障移动式回收
复制算法或标记-整理算法需移动对象,此时必须批量更新所有指向它的引用。仅靠屏障不够,还需配合:
- OopMap:在类加载或JIT编译时生成,精确记录每个栈帧/寄存器中哪些位置可能存有对象引用
- 安全点(Safepoint):在这些位置暂停所有Java线程,确保引用更新是原子且完整的
- 写屏障在此过程中跟踪堆外引用(如DirectByteBuffer的address字段),防止因JNI或NIO绕过JVM控制而遗漏修正
屏障不是万能的:它只管内存逻辑安全
屏障技术解决的是“不该回收的对象没被误删”“移动后引用仍有效”这类底层内存安全问题。它不感知业务语义:
- 不会阻止你把订单对象设为null后又去查它的支付状态
- 不介入数据库事务、分布式锁或缓存一致性协议
- 其目标是让GC过程本身可预测、可验证,而不是替你做数据校验或状态同步
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











