由于虚拟机的不同,我们在创建对象,访问对象时的方式也不同。
如果某方法中创建一个对象,比如: Object obj=new Object();
在java虚拟机的内存划分一文中说过,方法被调用的过程就是方法不断进栈的过程,也是栈帧不断创建的过程。栈帧中包含局部变量表,Object obj存储在栈帧的局部变量表中,是引用数据类型(reference)。
new Object()创建的对象实例存放在堆中,存放Object类型所有实例数据值(各个实例字段),形成一块结构化内存。由于具体实例的不同以及虚拟机类型的不同,内存所占用大小也不同。并且,在堆中也必须说明此实例的类型数据(比如实例类型,父类,实现的接口和方法)的地址,这些数据是存放在方法区中。
引用数据类型obj引用堆内存中实例的方式有两种:句柄方式和直接指针。
句柄方式:在堆中划分出一块句柄池,句柄中存放对象实例数据和对象类型数据信息,栈内存中的引用数据类型存放句柄地址。如下图(来源于深入理解java虚拟机一书):

直接指针方式:对象类型数据信息分布在对象实例中,栈内存中的引用数据类型直接引用对象地址。如下图(来源于深入理解java虚拟机一书):

两种方式的优势:使用句柄方式访问对象比较灵活,如果对象实例数据位置改变,比如说被垃圾回收机制回收掉,那么只需要改变句柄中的实例数据指针,reference本身不需要改变。使用直接指针方式速度会更快,因为毕竟在访问对象实例时只需要一次指针定位就可以完成,如果需要频繁的访问对象,会节省很多时间开销。Sun HotSpot是使用直接指针方式进行对象访问的。

3747

被折叠的 条评论
为什么被折叠?



