Mark Word 是 Java 对象头中动态复用的 64 位核心字段,依对象状态存储哈希码、锁信息(偏向/轻量/重量级)或 GC 标记,通过锁状态位隔离不同用途,支撑 synchronized、hashCode 和垃圾回收协同运行。

Mark Word 是 Java 对象头(Object Header)中最核心的字段之一,它不是固定存储某一种信息,而是根据对象当前状态动态复用同一块内存空间,主要服务于锁机制和垃圾回收两大关键场景。
Mark Word 存什么:一格多用的动态结构
在 64 位 JVM 中,Mark Word 占 64 位(8 字节),但不会同时存满所有内容。它的布局随对象状态切换,典型用途包括:
-
无锁状态:存放对象的哈希码(hashCode),仅在首次调用
hashCode()后写入;若未调用,则这部分可被后续锁状态复用 - 偏向锁状态:记录偏向线程 ID、偏向时间戳、是否启用偏向锁等,用于避免无竞争时的同步开销
- 轻量级锁状态:存指向当前线程栈中锁记录(Lock Record)的指针,配合 CAS 实现快速加锁/解锁
- 重量级锁状态:存指向 Monitor 对象的指针,此时锁已膨胀,进入操作系统级阻塞队列
- GC 相关标记:如分代年龄(GC age)、是否处于 GC 标记阶段(如 CMS 的 mark-bit、G1 的 TAMS 指针辅助位)等,不同 GC 算法会按需复用低位
锁标记位与 GC 标记不冲突,靠状态位隔离
Mark Word 通过高几位(通常是 2–3 位)定义锁状态标志(lock bits),例如:
- 001 → 无锁(normal)
- 101 → 偏向锁(biased)
- 000 → 轻量级锁(lightweight)
- 010 → 重量级锁(heavyweight)
而 GC 使用的标记信息(如分代年龄占 4 位、GC 标志位占 1 位)被安排在其余空闲位上。JVM 严格约定:同一时刻只有一种主导状态生效,GC 运行期间会暂停应用线程(STW)或采用读屏障保障一致性,因此不会出现锁位与 GC 位互相覆盖或误读。
立即学习“Java免费学习笔记(深入)”;
实际影响:你看不见,但它决定性能底线
Mark Word 的状态变化直接影响程序行为:
- 频繁调用
hashCode()后再加锁,可能触发锁膨胀(因哈希码已占用原偏向/轻量位) - 开启
-XX:-UseBiasedLocking后,偏向锁位不再使用,节省了部分判断开销 - G1 垃圾收集器在并发标记阶段会临时修改 Mark Word 的某些位(如设置 marked-in-bit),但仅在线程安全上下文中操作
- 使用 JOL(Java Object Layout)工具可打印对象头,观察 Mark Word 实际值变化,验证锁升级过程
基本上就这些。它不暴露给开发者直接操作,却是 synchronized、hashCode、GC 三者协同运转的隐性枢纽。











