对象在内存中的存储布局
时间:
在Java中,对象在内存中的存储布局通常包括以下几个部分:
- 对象头(Object Header):
- Mark Word:包含对象的运行时信息,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID等。Mark Word的大小取决于虚拟机的实现,通常是32位或64位。
- 类型指针(Class Pointer):指向对象的类元数据,确定对象的类型。并不是所有的虚拟机实现都有这一部分,有些虚拟机可能会使用其他方式来定位对象的类元数据。
- 数组长度(Array Length)(如果对象是数组):记录数组的长度,只有数组对象才有这部分。
- 实例数据(Instance Data):
- 这部分存储了对象真正的内容,即各个实例字段(非静态字段)的值。字段的存储顺序受到JVM规范的影响,但通常遵循以下规则:
1) 父类字段先于子类字段。
2) 字段按照申明顺序排列。
3) 如果字段大小是8字节对齐的,那么对象的起始地址需要对齐。
- 对齐填充(Padding):
- 这部分不是必须的,只是为了满足虚拟机对对象起始地址的特定对齐要求。例如,如果一个对象的大小是8字节的倍数,那么它可能会包含一些额外的填充字节,以确保下一个对象也按照8字节对齐。
以下是一个简化的对象内存布局示意图:
+------------------+------------------+------------------+
| Mark Word | Class Pointer | Array Length | (如果对象是数组)
+------------------+------------------+------------------+
| Mark Word | Class Pointer | | (如果对象不是数组)
+------------------+------------------+------------------+
| Instance Data | | |
| (Fields) | | |
+------------------+------------------+------------------+
| Padding | | |
+------------------+------------------+------------------+
需要注意的是,不同的JVM实现可能会有不同的内存布局细节,上述描述是基于常见的HotSpot虚拟机的实现。