开篇:一个 Java 对象在内存里长什么样?
写了几年 Java,你可能 new 过成千上万个对象,但有没有想过:new Object() 在堆内存中到底占多少字节?一个只有一个 int 字段的类,和一个空对象差多少?
这些问题的答案,直接影响到你对锁升级、GC 年龄、对象头压缩等知识的理解。所以在深入 synchronized 锁升级之前,我们先把"对象在内存里长什么样"这件事搞清楚。
一、对象的三部分
在 HotSpot 虚拟机中,一个对象在堆内存中由三部分组成:
┌─────────────────────────────────────────┐
│ 对象头 (Header) │
│ ┌──────────────────────────────────┐ │
│ │ Mark Word (标记字段) │ │
│ │ 8 bytes (64位VM) │ │
│ ├──────────────────────────────────┤ │
│ │ Klass Pointer (类型指针) │ │
│ │ 4 bytes (压缩) / 8 bytes (不压缩)│ │
│ └──────────────────────────────────┘ │
├─────────────────────────────────────────┤
│ 实例数据 (Instance Data) │
│ 存放类中定义的字段(含父类字段) │
├─────────────────────────────────────────┤
│ 对齐填充 (Padding) │
│ 补齐到 8 字节的整数倍 │
└─────────────────────────────────────────┘
大约 6 分钟