46.对象的内存布局(对象头、实例数据、对齐填充)和对象的访问定位(句柄访问和直接指针)

 

1.对象的内存布局

在这里插入图片描述
1.整体上来看,对象在内存中有3部分,对象头、实例数据、对齐填充。
a)对象头包含运行时元数据和类型指针。运行时元数据包含哈希值(这个哈希值就是创建出来的对象在内存中的地址)、GC分代年龄、锁状态标志等。类型指针,指向方法区(元空间)中对象所属的类型。如果创建的是数组,对象头还会保存数组的长度。
b)实例数据。类中定义的成员变量。规则:先放父类的成员变量,在放子类的成员变量。相同宽度的变量被放在一起。如果compactFileds参数为true,子类的窄变量可能插入到父类变量的空隙。
c)对齐填充
2.如下图所示,比较详细的解释了对象的内存布局以及它和栈、方法区之间的联系。
虚拟机栈中保存的是一个个栈帧,栈帧中是一个个成员变量,其中cust成员变量指向了堆空间中创建的Customer()实例,对象实例包含对象头、实例数据、以及对齐填充。
其中对象头又包含运行时元数据、类型指针;运行时元数据包含哈希值、GC分代年龄、锁状态标志等;类型指针指向方法区中Customer对象的类型信息。
实例数据包含的是类Customer中定义的成员变量信息。其中name是一个字符串常量,指向了字符串常量池中的字符串常量(注意,字符串常量池在JDK7就已经被移动到了堆区);acct是一个对象的引用,又指向了一个堆区中新的对象。
最后一部分对齐填充,主要是为了内存字节对齐。

在这里插入图片描述

2.对象的访问定位

在这里插入图片描述
对象访问的方式有两种:句柄访问和直接指针。
1.句柄访问。
Java堆中将会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息。
在这里插入图片描述
2.直接指针(HotSPot虚拟机采用)。
reference中直接存储的就是对象地址,对象中存储了到对象类型的类型指针。
在这里插入图片描述
优缺点:
1.使用句柄的方式,需要开辟一块独立的空间给句柄池;同时访问对象效率较低,需要通过两次指针。句柄稳定,对象被移动只要修改句柄中的地址。
2.使用直接指针的方式,访问速度快,节省了一次指针定位的开销

posted @ 2020-11-18 18:29  跃小云  阅读(310)  评论(0编辑  收藏  举报