对象访问

阅读:157

 

1.什么是对象访问

假如现在在一个方法体中,有如下代码:

Object obj = new Object();

Object obj,是一个引用(reference)类型,在JVM中是存储在Java栈的本地方法表中。new Object(),这个创建了一个对象,存储在Java堆中,在堆中存储了Object的实例数据值(Instance Data),也就是实例字段的数据。在该堆中存储数据的长度,根据不同的虚拟机不同而不同。

在堆中还存储了对象数据类型的地址信息,如对象类型、父类、接口、方法等,存储在方法区中。

那么通过引用如何查找到实际的对象的过程,叫做对象访问。该例中是通过obj引用查找new Object()这个对象。

2.如何进行对象访问?

在Java虚拟机规范中,引用类型变量只规定了一个指向对象的引用地址,而没有规定通过什么方式访问定位到具体堆中对象的位置,所以不同的虚拟机实现方式不同。主流的访问方式有两种:

  • 通过句柄
  • 直接指针

2.1 通过句柄访问对象

通过该方式实现访问的对象的虚拟机,会在Java堆中存储一个句柄池,该池中有很多存储了很多句柄。句柄的内容为对象的实例数据和类型数据各自的具体地址信息。而引用类型是在Java栈中,引用存储的是对象的句柄地址。具体访问方式如下:

引用类型通过自身存储的句柄地址,找到句柄,再通过句柄存储的对象的实例数据和类型数据的地址,查到到具体的对象的实例数据和类型数据。也就是如下:

引用类型(句柄地址)---> 句柄(对象的实例数据和类型数据地址)---> 对象(实例数据或类型数据)

2.2 通过直接指针访问对象

如果通过直接指针访问对象,引用类型存储的直接是对象地址,而对象中存储了类型数据的地址。

这样引用类型可以直接通过对象地址访问到对象。

3.句柄和直接指针访问的优缺点

  • 句柄访问的优势是引用存储的是句柄地址,改地址是稳定地址,不会因为对象的变化移动而作出改变。我们知道,垃圾收集是经常发生的,对象的地址也会经常做出改变,而当地址改变的时候,只需要改变句柄内存储的对象的地址信息。

  • 句柄访问的缺点是相较于直接指针访问是多了一次引用到句柄的指针访问,该指针定位的时间开销,在频繁的Java对象访问中,也是非常可观的开销。

  • 直接指针访问的优缺点和句柄完全相反,优势是少了句柄的访问步骤,速度快。缺点是频繁对象地址改变,引用中存储的对象地址也要一起改变。

    在 Sun HotSpot虚拟机中,使用的就是直接指针访问。但是,句柄访问也是比较常见的。

 

 

读后有收获,请打赏。更多精彩内容,请关注微信公众号。有疑问请加QQ交流群:454792501

全部评论

发表评论
更多精彩内容,请关注微信公众号