一个普通java对象在hotspot堆内存中由对象头、实例数据、对齐填充三部分顺序构成:对象头含mark word(8字节)和类型指针(4或8字节),数组额外加4字节长度;实例数据按字段宽度降序排列并自然对齐;对齐填充确保总大小为8字节倍数。

一个普通Java对象在堆内存中的布局由三部分组成:对象头(Object Header)、实例数据(Instance Data)和对齐填充(Padding)。这是HotSpot虚拟机的实现规范,适用于64位JVM(默认开启指针压缩时)。
对象头:存储元信息与锁状态
对象头通常占12字节(开启指针压缩)或16字节(关闭指针压缩),分为两部分:
- Mark Word(8字节):存储哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。其内容随对象状态动态变化,例如无锁时存hashCode,加锁后可能存指向Monitor的指针。
- Class Pointer(4字节,开启指针压缩)或8字节(关闭):指向该对象所属类的Klass结构体在方法区(元空间)中的地址,用于类型判断和方法分派。
实例数据:成员变量的实际存储区域
紧跟对象头之后,按宽度从大到小排序存放字段(JVM优化策略),相同宽度字段会紧凑排列。父类字段在前,子类字段在后。
- 基本类型按自身大小占用:long/double占8字节,int/float占4字节,short/char占2字节,byte/boolean占1字节(注意:boolean不单独映射为1字节存储,但JVM按1字节对齐处理)。
- 引用类型统一占4字节(开启指针压缩)或8字节(关闭),实际指向堆中另一对象起始地址。
- 字段重排序是JVM合法优化行为,不影响语义,但会影响内存占用和缓存局部性。
对齐填充:保证对象起始地址为8字节倍数
HotSpot要求每个对象起始地址必须是8字节的整数倍(即满足“8字节对齐”),因此若对象头+实例数据总大小不是8的倍数,会在末尾补零(padding)。
- 例如:对象头12字节 + int字段4字节 = 16字节,无需填充;若只有1个byte字段,则总长12+1=13,需填充3字节达到16字节。
- 填充本身不存任何逻辑数据,仅用于满足内存对齐硬件要求,提升CPU访问效率。
这种结构决定了对象的最小内存占用(如空对象:12字节头 + 4字节填充 = 16字节),也解释了为什么合理安排字段顺序(宽字段优先)可减少填充浪费。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











