Java对象中的MarkWord
一、Java对象的内存结构
每个Java对象在内存中由三部分组成(以64位JVM为例):
|---------------------------------|
| 对象头 (12-16字节) | → 包含Mark Word和类型指针
|---------------------------------|
| 实例数据 (不定长) | → 存储对象的字段值
|---------------------------------|
| 对齐填充 (0-7字节) | → 确保对象总大小为8的倍数
|---------------------------------|
二、Mark Word的核心作用
Mark Word是对象头的核心部分(固定8字节),用于存储对象的运行时状态,包括:
- 🔐 锁状态(无锁、偏向锁、轻量级锁、重量级锁)
- 🆔 哈希码(对象的唯一标识)
- 🧓 GC分代年龄(对象被垃圾回收的次数)
- 🧵 线程ID(持有偏向锁的线程)
- ⏰ 时间戳(偏向锁的时效性验证)
📌 关键设计:Mark Word像变色龙一样复用存储空间,根据对象状态动态调整内容。
三、Mark Word的结构变化(锁升级视角)
下图展示64位JVM下Mark Word在不同锁状态时的结构变化:
| 锁状态 | Mark Word结构 (64位) | 标志位 |
|-------------|-----------------------------------------------|--------|
| **无锁** | 哈希码(31位) \| 分代年龄(4位) \| 0 \| **01** | `01` |
| **偏向锁** | 线程ID(54位) \| Epoch(2位) \| 1 \| **01** | `01` |
| **轻量级锁**| 指向栈中锁记录的指针(62位) \| **00** | `00` |
| **重量级锁**| 指向重量级锁(Monitor)的指针(62位) \| **10** | `10` |
| **GC标记** | (空) \| **11** | `11` |
🔍 锁升级过程(以线程竞争为例):
无锁 → 偏向锁(单线程反复访问)→ 轻量级锁(少量竞争,CAS自旋)→ 重量级锁(激烈竞争,线程阻塞)。
四、核心字段详解
-
分代年龄 (4位)
- 记录对象被GC的次数(最大值15,因4位二进制最大值为
1111=15
) - 达到阈值后对象从年轻代晋升到老年代。
- 记录对象被GC的次数(最大值15,因4位二进制最大值为
-
哈希码 (31位)
- 调用
hashCode()
后生成,延迟存储到Mark Word - 加锁后因空间不足,会迁移到Monitor中。
- 调用
-
线程ID (54位)
- 偏向锁状态下记录持有锁的线程ID
- 同一线程再次加锁时直接通行(无同步开销)。
五、实战观察工具 - JOL
使用JOL库(Java Object Layout)直接打印对象内存布局:
// 添加Maven依赖
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.17</version>
</dependency>// 打印Object对象布局
public static void main(String[] args) {Object obj = new Object();System.out.println(ClassLayout.parseInstance(obj).toPrintable());
}
输出示例(无锁状态):
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION
0 4 (object header) 01 00 00 00 # Mark Word (01表示无锁)
4 4 (object header) 00 00 00 00 # 类型指针 (压缩后4字节)
8 4 (alignment padding) # 对齐填充
Instance size: 16 bytes
🔑 锁状态验证:
在synchronized
代码块内打印对象布局,可见标志位从01
变为00
(轻量级锁)。
六、为什么这样设计?
-
空间极致利用
- 通过动态复用8字节空间,避免为每种状态分配独立空间。
-
性能优化
- 偏向锁减少无竞争时的同步开销
- 轻量级锁用CAS避免线程阻塞。
-
扩展性
- 标志位决定结构,未来可扩展新状态(如JDK15的ZGC标记位
11
)。
- 标志位决定结构,未来可扩展新状态(如JDK15的ZGC标记位
七、总结:Mark Word的核心角色
功能 | 实现机制 |
---|---|
身份证明 | 存储哈希码和GC年龄 |
锁管理 | 通过标志位切换锁状态 |
线程协同 | 记录持有锁的线程ID |
内存优化 | 动态复用存储空间 |
💎 一句话理解:
Mark Word是Java对象的智能身份证,既存储身份信息(哈希码/年龄),又动态反映当前状态(锁类型),以最小空间支撑JVM的高效运行。