shenandoah 仍以 brooks pointer 为核心转发机制,load-reference barrier 是其读屏障的精确命名而非替代方案;它依赖对象头中的 forwarding pointer 字段实现并发移动,与 zgc 的染色指针本质不同。

这个说法不准确。截至 JDK 23(当前最新稳定版,2026 年中),Shenandoah 仍在使用 Brooks Pointer 作为其核心转发机制,并未被 Load-Reference Barriers 替代。
Brooks Pointer 仍是 Shenandoah 的基础设计
Shenandoah 的对象移动一致性完全依赖 Brooks Pointer:每个对象头内(或紧邻)保留一个原子可更新的 forwarding pointer 字段。当对象被并发复制后,GC 线程通过 CAS 将该指针从指向自身改为指向新副本地址。所有后续读取操作都必须经过读屏障检查该指针,并自动跳转——这是 Shenandoah 实现“无需 STW 移动对象”的根本保障。
- 该机制自 JDK 12 引入起未被移除,JDK 15 正式转正、JDK 17/21/23 持续优化的都是同一套 Brooks 指针模型
- 官方文档、OpenJDK 源码(如
shenandoahBarrierSet::load_reference_barrier)和 JVM 参数(如-XX:+ShenandoahLoadRefBarrier)均表明:读屏障是作用于 Brooks Pointer 的检查逻辑,而非替代它 - 所谓 “Load-Reference Barrier” 是 Shenandoah 中对读屏障的更精确命名(强调它拦截的是引用类型的 load 操作),但它本身不改变底层转发语义,仍需访问并解引用对象头中的 fwdptr 字段
与 ZGC 的染色指针有本质区别
ZGC 确实不依赖对象头字段,而是靠指针高位编码 + 多重内存映射实现无转发字段的并发移动。它的读屏障是纯地址位运算,不访问堆内存。但 Shenandoah 的设计哲学不同:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 它选择显式存储转发信息在对象头,换来更强的平台兼容性(全平台支持,包括某些不支持 mmap 多映射的嵌入式环境)
- 它接受每个对象 +8 字节开销和一次间接跳转成本,换取实现简洁性和对 JIT 友好的内存访问模式
- 没有计划用 ZGC 风格的染色指针取代 Brooks Pointer;二者是并行演进的不同技术路线
关于“替代”说法可能的来源
部分社区讨论或旧资料中提到的 “Load-Reference Barrier 优化”,实际是指:
- JDK 13 起对原有读屏障做精细化拆分,区分普通 load 和引用类型 load,减少非必要开销
- JDK 17+ 引入的
-XX:+ShenandoahSATBBarrier或-XX:+ShenandoahWriteBarrier等开关,用于调试或特定场景裁剪,但不关闭 Brooks Pointer 依赖 - 将“读屏障”统称为 “Load-Reference Barrier” 是术语规范化,不是架构替换
简言之:Brooks Pointer 是 Shenandoah 的骨骼,读屏障(含 Load-Reference Barrier)是附着其上的肌肉——肌肉可以锻炼优化,但不会把骨头换掉。










