Java对象在堆内存中严格按对象头、实例数据、对齐填充三部分顺序构成物理连续结构:对象头含Mark Word(8字节)和类型指针(4字节),实例数据按字段宽度降序排列,对齐填充确保总大小为8字节倍数。

Java对象在堆内存中不是随意堆放的,而是严格按三部分组织:对象头、实例数据、对齐填充。这三块共同构成一个物理连续的内存块,每部分都有明确职责和约束。
对象头:对象的元信息容器
对象头紧贴对象起始地址,存放运行时关键元数据,主要包括:
- Mark Word:记录哈希码、GC分代年龄、锁状态(无锁/偏向/轻量级/重量级)、线程ID等,32位JVM占4字节,64位默认开启指针压缩时占8字节
- Class Pointer:指向该对象所属类的Klass结构体地址,用于类型识别和方法查找;64位+压缩指针下占4字节(未压缩为8字节)
- Array Length(仅数组):4字节,存数组长度,所以普通对象没有这一项
以64位HotSpot JVM开启压缩指针为例,普通对象头固定为12字节(8+4),数组对象头为16字节(8+4+4)。
实例数据:你定义的字段真实落脚地
这部分紧随对象头之后,存放所有字段的实际值,包括本类声明的字段和父类继承下来的字段。JVM会按字段宽度重新排序,优先放置long/double → int/float → short/char → byte/boolean,以减少后续填充量。
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
例如:boolean b; int i; long l; 不会按声明顺序排布,而大概率是 long l; int i; boolean b,再加3字节填充使i对齐——这是为了提升CPU读取效率,不是Java语法决定的。
对齐填充:让总大小凑成8字节倍数的“补白”
对齐填充没有业务含义,不存任何数据,但它必不可少。HotSpot强制要求:
- 对象起始地址必须是8字节对齐(即地址 % 8 == 0)
- 整个对象占用的总字节数必须是8的整数倍
计算公式为:(8 − (对象头 + 实例数据) % 8) % 8。比如对象头12B + 字段共5B = 17B → 需补7B → 总长24B;若合计刚好24B,则填充为0。
根本原因在于CPU缓存行通常是64字节(8×8),对齐后能避免伪共享(False Sharing),也保障CAS等原子指令正常执行。

















