Java对象头Mark Word是动态复用的64/32位区域,依锁状态存储不同信息:无锁态存hashcode、GC年龄和标志位01;偏向锁态存线程ID、epoch和年龄;轻量级锁态存指向栈中Lock Record的指针;重量级锁态存指向堆中Monitor的指针;GC标记态用11标识。

Java中对象头的Mark Word不是固定结构,而是随锁状态动态复用的64位(或32位)内存区域。它的核心作用是用最少的位数表达最多的状态信息——同一段空间,在不同锁状态下存储完全不同的内容。
无锁状态:空闲但可记录基本信息
标志位为01,且偏向位(biased_lock)为0。此时Mark Word主要存放三类数据:
- 31位identity_hashcode(未调用System.identityHashCode()时为空)
- 4位GC分代年龄(最大值15)
- 保留位与锁标志位组合(01)
注意:hashCode是延迟计算的,首次使用才写入;一旦后续加锁,这部分空间会被覆盖,hashCode会转移到Monitor中暂存。
偏向锁状态:单线程专属“通行证”
标志位仍为01,但偏向位变为1。此时Mark Word腾出54位存持有线程ID、2位存epoch(用于批量撤销)、4位保留年龄字段。
立即学习“Java免费学习笔记(深入)”;
本质是一次CAS换长期免检:首个线程进入synchronized块时尝试将自身ID写入Mark Word;成功后,该线程后续再进同一把锁,直接比对线程ID即可放行,无需任何同步操作。
轻量级锁状态:多线程下的栈上博弈
标志位变为00,偏向位失效。Mark Word不再存线程ID,而是存一个62位指针,指向当前线程栈帧中的Lock Record。
- 每个竞争线程在自己栈上新建Lock Record,并复制原Mark Word内容
- 用CAS尝试将Mark Word替换为指向该Lock Record的指针
- 失败者进入自旋等待,检测Mark Word是否恢复为无锁态或被其他线程占用
- 默认自旋上限10次,超限即触发升级
重量级锁状态:操作系统级阻塞
标志位为10,Mark Word存一个62位指针,指向堆中Monitor对象。
Monitor包含Owner(持锁线程)、EntryList(阻塞队列)、WaitSet(等待队列)。此时线程进入阻塞态,依赖操作系统互斥量实现同步,伴随用户态/内核态切换开销。
GC标记状态用11表示,不属于锁状态,仅用于垃圾回收识别。


















