对象的内存布局包括三部分:对象头、实例数据、对齐填充。
1 对象头
对象头中又包括两部分:对象标记、类元信息(类型指针)。其中对象标记占8个字节、类元信息占4个字节,对齐填充(填充到8的倍数字节)4字节,共占用16个字节。以上是开启压缩指针的情况下,会将类元信息压缩至4字节,关闭压缩指针时类元信息占用8个字节,则对象标记与类元信息各占8字节,共16字节满足8的倍数字节,不需要对齐填充。
1.1 对象标记
对象标记占8个字节,一个字节是8位,即占64位。下图是64位的组成。
该图是上图中锁标志位所代表的含义,在运行期间对象标记中的数据会随着锁标志位的变化而变化。
1.2 类元信息
对象头的一部分,又叫类型指针,该指针指向java虚拟机元空间中的kclass类元信息,虚拟机通过该指针确定该对象是哪个类的实例。
2 示例数据
存放类的属性(Field)数据信息,包括父类的属性信息。如下代码User类中的age、isAlive属性就存储在对象的实例数据中。
class User {
int age;
boolean isAlive;
}
3 对齐填充
java虚拟机要求对象的起始地址必须是8字节的整数倍,对齐填充就是用来填充大小不足8字节整数倍的对象。
如上User类为例,对象头占12字节(对象标记8字节、类型指针4字节、后续还有类属性则先不对齐填充)、int类型占4字节、boolean类型占1字节,共占用17字节。由于不满足jvm对象8字节整数倍的规范,则需要再填充7字节,则满足8的整数倍24字节的要求。