在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块:对象头,实例数据,对齐填充。
一、对象头
对象头包含两部分信息,
(1)是存储对象自身运行时元数据(官方称“Mark Word”),如哈希、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳。
(2)类型指针,对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪一个类的实例。并不是所有的虚拟机实现都必须在对象数据上保留类型指针,即查找对象的元数据信息并不一定要经过对象本身。
二、实例数据(对象真正存储的有效信息)
这部分存储顺序会受到虚拟机分配策略参数和字段在java源码中定义顺序的影响。HotSpot虚拟机默认的分配策略为longs/doubles、ints、shorts/chars、bytes/booleans、oops。相同宽度的字段会被分配到一起。在满足这个前提条件的情况下,在父类中定义的变量会出现在子类之前。如果CompactFields参数为true(默认是true),那么子类之中较窄的变量也可能会插入到父类变量的空隙之中。
三、对齐填充
对齐填充不是必然存在的,也没有特别的含义,它仅仅是占位符的作用。由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍。而对象头部正好是8字节的倍数(1或者2倍)。当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。
四、图示