一. 对象头
1. 运行时元数据(Markword)
- 哈希值(HashCode): 如果不调用Hashcode()Jvm是不会分配hashcode到对象头。Hashcode存在的作用就是方便对象有效合理的在散列数据结构中的存储。(类似于重写eqlus也必要重写hashcode来保证数据的唯一性)
- GC信息:记录对象的分代回收年龄。
- 锁信息:锁状态标志位,线程持有的锁,偏向线程ID等等。
2. 类型指针
即对象指向它的类型元数据的指针,Jvm可以通过指针找出该对象是由哪个类实例化而来。
3. 数组
如果Java的对象是数组,那么对象头还会有一个数据用来记录数组的长度。
二. 实例数据
实例数据部分存储了对象的有效信息。值得注意的是实例部分只会存储对象属性的值(通过类型指针找到元空间中的类型元数据中的属性名对应的偏移量,然后根据堆中对象的开辟内存空间为起点,找到对应属性的值并返回)。
三. 对齐填充
仅仅起到占位的作用。hotspot虚拟机的内存管理要求对象大小必须是8字节的整数倍。