java对象的结构是由Header对象头、InstanceData、Padding组成
目录
-
Header(对象头)
1、自身运行时的数据(Mark Word)
HotSpot虚拟机对象头 Mark Word
(根据系统虚拟机大小不同其大小不同,32位虚拟机数据大小为32位,64位系统虚拟机数据大小为64位)
存储内容:
哈希值(hashCode()方法是native)
GC分代年龄(为分代收集算法所服务 分代好处:针对各个年龄代特点,选择适当的垃圾收集算法。)
锁状态标志
线程持有的锁
偏向线程ID
偏向时间戳
2、类型指针(Class Metadata Address)
对象指向类的元数据的指针,虚拟机通过这个指针来确定对象是哪一个类的实例,并不是所有jvm实现都必须在对象数据上保留类型指针
3、作为普通对象的对象头结构只有以上两种,但如果对象是一个数组,则对象头中还包含记录数组长度的数据
-
InstanceData
数据的实例信息,真正存储对象有效信息的部分,我们所接触最多的部分。不管是从父类继承中获得的还是从子类定义的实例信息,都被记录在其中。这部分的存储顺序由虚拟机的分配策略和字段在Java源码中定义的顺序决定,HotspotVM默认策略——相同宽度的字段分配到一起,如 long/double类型、short/char 分配到一起。在父类中定义的对象,可能出现在子类之前。
-
Padding
这部分数据并不是必然存在的,它也没有特殊的含义。作用是作为一个占位符,用于填充内存。为什么需要padding? 主要因为HotspotVM自动内存管理系统要求对象起始地址必须是8个字节的整数倍,也就是说对象的大小必须是8个字节的整数倍,而对象头部分整好是8个字节的整数倍。因此,对象实例数据部分如果没有对齐是就需要通过padding来进行填充。