我们知道在java中创建新对象的时候会产生一个引用类型和实例对象。

引用类型(reference):保存的是实例对象的引用,存储在栈中
实例对象:存储在堆中
注:新建实例对象的时候JVM同时会加载实例对象java类文件,将实例对象的类型信息保存在方法区中,后面我们可以看到访问对象的时候会同时去方法区中访问类型信息。

由于JVM规范中reference类型只定义了一个指向对象的引用,并没有定义引用如何去定位这个对象,因此不同的虚拟机有不同的方式去访问对象,主流的对象访问方式有两种:使用句柄和直接指针。

句柄方式

当使用句柄方式访问,java堆中会分出一块内存作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了实例对象数据和类型数据的两个具体地址信息,如下图:
JVM之对象访问详解

直接指针方式

当使用直接指针方式访问,java堆对象的布局中就必须考虑如何存放访问对象类型数据的相关信息,因为reference中存储的就是对象地址,如下图。
JVM之对象访问详解

总结

  1. 使用句柄的最大好处是 reference 中存储的是稳定的句柄地址,在对象移动(GC)是只改变实例数据指针地址,reference 自身不需要修改。
  2. 直接指针访问的最大好处是速度快,节省了一次指针定位的时间开销。
  3. 如果是对象频繁GC那么句柄方法好,如果是对象频繁访问则直接指针访问好。

相关文章: