Java中对象访问仅使用直接指针方式,HotSpot自JDK 1.3起废弃句柄访问;栈中reference直接存对象地址,单次寻址即可访问,比句柄方式快12%~18%,且支持ZGC等并发GC的精确标记。

Java 中对象访问不直接暴露句柄或指针,但 JVM 实现(如 HotSpot)内部确实存在两种典型对象访问方式:句柄访问和直接指针访问。它们的差异体现在对象定位机制上,直接影响 GC 期间对象移动时的处理逻辑。
句柄访问:通过稳定中间层解耦对象位置
句柄访问将堆内存划分为两个区域:句柄池(独立区域,通常在 Java 堆外或堆内固定位置)和对象实例数据区。每个对象在句柄池中有一个对应句柄,句柄中存有对象实例数据的地址(即指针)和类型元数据地址。
- GC 移动对象时,只需更新句柄中的实例地址字段,所有引用该对象的栈/寄存器仍保存句柄地址(不变),无需修正
- HotSpot 虚拟机未采用此方式,但它是理解 GC 友好性的经典模型;某些嵌入式 JVM 或早期实现曾使用
- 优势在于引用稳定性高,适合频繁移动对象的 GC 算法(如复制、标记-整理)
直接指针访问:HotSpot 的实际选择
HotSpot JVM 使用直接指针访问:栈帧中的引用(reference)直接存储对象在堆中的起始地址(即指向对象头)。这是目前主流 JVM 的默认实现。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 访问速度快——省去一次句柄查表跳转,对象字段读写更直接
- GC 移动对象时(如 G1 或 ZGC 的并发整理阶段),必须扫描并更新所有指向该对象的引用(包括 Java 栈、本地栈、静态变量、其他对象字段等)
- 依赖写屏障(Write Barrier)和卡表(Card Table)、记忆集(Remembered Set)等机制追踪跨代/跨区域引用,确保移动后引用及时修正
GC 过程中如何保证引用一致性
无论哪种方式,JVM 都需在 GC 安全点(safepoint)暂停线程,或借助并发机制(如 ZGC 的读屏障、Shenandoah 的 Brooks 指针)实现无停顿更新。
立即学习“Java免费学习笔记(深入)”;
- 直接指针下,CMS/G1 在 Remark 阶段做精确根扫描;ZGC 用读屏障拦截对象加载,动态重映射地址
- 句柄模式下,GC 只需遍历句柄池并更新实例字段,引用本身无需改动
- 现代 JVM 不暴露句柄概念给 Java 程序员,Object 引用始终是抽象的“reference”,其底层是地址还是句柄由 VM 决定
为什么 HotSpot 选直接指针而非句柄
性能权衡是核心原因:Java 应用对对象访问频率极高,减少一层间接寻址带来可观收益;而 GC 移动成本可通过优化(如增量更新、并发转移)摊销。
- 句柄池本身需要额外内存与缓存开销,且可能成为热点竞争点
- 现代硬件对局部性敏感,直接指针有利于 CPU 缓存行利用
- HotSpot 的分代 GC 和区域化 GC(G1/ZGC)已具备成熟机制处理指针更新,不再依赖句柄的“天然稳定性”

















