【深入理解JVM】 3.对象的内存布局和访问定位
本节主要讲的是HotSpot VM
-
对象的内存布局
在hotspot vm中,内存布局分为对象头(Header)、实例数据(Instance Data)、对齐填充
1.对象头:存储对象自身的运行时数据和类型指针。如果是数组的话,对象头中还应有记录数组长度的数据。
1.1:对象自身的运行时数据包括HashCode、GC分代年龄、锁状态标志、线程持有的锁等
1.2:类型指针,即对象指向它的类元数据的指针,VM通过该指针判断对象是哪个类的实例。
2.实例数据:存储代码中定义的各种类型的字段内容,是对象真正存储的有用信息。
这部分存储会受JVM的分配策略参数和字段在Java源码中定义的顺序影响。
3.对齐填充:无特殊含义,仅起占位符的作用
因为HotSpot中的自动内存管理系统规定对象的大小必须是8字节的整数倍,而对象头正好是8字节的1倍或者2倍,实例数据部分如果不是8字节的倍数,可以有对齐填充来补全。
-
对象的访问定位
目前主流的访问方式是:句柄访问和直接指针
句柄访问
java堆中会划出一块内存作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自的具体地址信息。如图:
优点:reference中存储的是稳定的句柄,对象如果移动,只会修改句柄中的实例数据指针,reference本身不会修改。
直接指针
reference中存储的直接就是对象地址。如图:
优点:速度快,因为节约了一次指针定位的时间。(HotSpot中运用的就是该方法) 。