Java 程序在运行时会通过 JVM 栈中本地变量表的 reference (引用)来操作堆上的对象。但是 reference 只是 JVM 规范中的一个指向对象的引用而已,这个引用具体如何定位到对象,JVM 没做限制,因此,不同的虚拟机可能有不同的实现,主要会有两种:句柄池和直接指针
使用句柄访问
堆中需要开辟一块叫做“句柄池”的内存空间,
句柄中的每条记录包含了对象实例数据的指针和对象类型数据的指针
reference 存放的是该对象的句柄内存地址。
访问对象时,首先需要通过 reference 找到该对象的句柄,然后根据句柄中对象的内存地址找到对象。
优缺点
优点:reference 存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而 reference 存储的句柄内存地址不需要改变
缺点:增加了一次指针定位的开销
使用指针访问
reference 中直接储存对象实例在堆中的内存地址,但对应的,对象实例数据中,必须存储对象类型数据的访问地址
优点:节省了一次指针定位的开销。 缺点:在对象被移动时 (如进行 GC 后的内存重新排列),reference 本身需要被修改
另外,直接指针是目前大部分的 JVM 虚拟机,包括 HotSpot 在内的实现方式