java对象在jvm堆中呈三段式结构:对象头(含mark word、klass pointer及数组长度)、实例数据(字段按宽度重排存储)和对齐填充(补至8字节整数倍);例如new object()在64位压缩指针下占16字节。

Java 对象在 JVM 堆内存中不是随意堆放的,而是有严格、固定的三段式结构:对象头、实例数据、对齐填充。理解这个布局,等于看清了对象在内存里的“身份证+身体+站位”。
对象头:对象的元信息中枢
对象头是每个对象必有的控制中心,包含两类关键字段:
- Mark Word(8 字节):动态复用的空间,存储哈希码、GC 分代年龄、锁状态(无锁/偏向锁/轻量级锁/重量级锁)、GC 标记等。内容随对象状态实时切换,靠位掩码区分。
- Klass Pointer(类指针,4 或 8 字节):指向方法区(JDK8+ 是元空间)中该对象所属类的元数据。开启压缩指针(默认开启)时占 4 字节;否则为 8 字节。
- 数组对象额外多一个 Array Length(4 字节),记录长度;普通对象没有这一项。
所以,在 64 位 JVM + 压缩指针下,普通对象头固定为 12 字节(8 + 4);数组对象则是 16 字节(8 + 4 + 4)。
实例数据:对象真正存的东西
这部分紧接对象头之后,存放你代码里定义的所有字段值,比如 int id、String name、boolean flag 等。
- JVM 会按宽度重排字段顺序:先放 long/double,再 int,再 short/char,再 byte/boolean,引用类型(4 或 8 字节)穿插在空隙中,以节省空间。
- 父类字段一定排在子类字段前面,这是继承语义的内存体现。
- 字段是否被访问、是否 final,不影响布局位置,只影响 JIT 优化行为。
对齐填充:让对象大小变成 8 字节整数倍
JVM 要求每个对象占用的总字节数必须是 8 的倍数,这是为了 CPU 高效读取和缓存行对齐。
- 如果对象头 + 实例数据加起来是 25 字节,就自动补 3 字节的 padding,凑成 32 字节。
- 填充字节不存任何逻辑数据,纯粹是“占位”,但会影响对象内存开销——尤其在集合中存大量小对象时,padding 成本会被放大。
实际算一算:new Object() 占多少?
以 64 位 JVM、开启压缩指针为例:
- 对象头:Mark Word(8) + Klass Pointer(4) = 12 字节
- 实例数据:Object 类无任何字段 → 0 字节
- 当前总大小:12 字节 → 不是 8 的倍数 → 补 4 字节 padding
- 最终大小:16 字节
你可以用 JOL(Java Object Layout)工具验证:new Object() 确实占 16 字节,不多不少。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











