前两篇讲了对象创建的底层细节, 也知道了创建的对象在内存中的布局和存储的内容。
那我们创建对象,肯定是为了访问它,使用它,那怎么访问它呢?
本篇继续讲一下Java对象的访问定位
建立对象是为了使用对象,我们的Java程序需要通过栈上的reference数据来操作堆上的具体对象。由于reference类型在Java虚拟机规范中只规定了一个指向对象的引用,并没有定义这个引用应该通过何种方式去定位访问堆中的对象的具体位置,所以对象的访问方式取决于具体的虚拟机实现而定。目前主流的访问方式有使用句柄和直接指针两种。
1、先讲一下使用句柄的访问方式
如图所示,如果使用句柄访问的话,那么Java堆中将会划分出一块内存来作为句柄池,句柄池中放的是一个一个的句柄,句柄中存的是对象实例数据与对象类型数据的指针引用。栈中局部变量里reference中存储的是对象句柄的地址,而句柄中包含了对象实例数据与类型数据的具体地址信息,相当于二级指针
2、第二种访问方式是直接指针
如图所示,直接指针访问对象,栈中局部变量里reference中存储的就是对象地址,相当于一级指针。
3、对比
这两种对象访问方式各有利弊,使用句柄访问的最大好处就是在移动对象时(如垃圾回收的标记整理算法在回收完垃圾对象后需要把剩下存活的对象进行整理移动,以减少内存碎片),reference中存储的地址是稳定的地址,不需要修改,仅需要修改对象句柄的地址;但是如果使用直接指针方式的话,在对象被移动的时候需要修改reference中存储的地址。从效率方面比较的话,直接指针的效率要高于句柄,因为直接指针的方式只进行了一次指针定位,节省了时间开销,HotSpot采用的直接指针的实现方式。
好了上述就是对Java对象的访问定位的理解与总结,如有错误的地方可以在评论区指出。
接下来会抽时间总结一下JVM垃圾回收的知识,感兴趣的小可爱可以继续关注一下