Mark Word是Java对象头中存储锁状态等元数据的关键字段,64位JVM中占8字节,低3位标识锁状态:001无锁、101偏向锁、000轻量级锁、010重量级锁、111 GC标记;锁状态随竞争动态升级,通过CAS修改Mark Word实现。

Java中对象的Mark Word是对象头(Object Header)的关键组成部分,用于存储对象的运行时元数据,其中就包括锁状态信息。它通过复用同一段内存空间、按位编码不同状态,实现轻量级锁、偏向锁、重量级锁等锁机制的快速切换。
Mark Word 的结构与锁状态位布局
在64位HotSpot虚拟机中(开启指针压缩,默认情况),Mark Word占用64位(8字节)。其中低3位(bit 0~2)固定用作锁状态标识,其余位根据锁状态动态解释:
- 001:无锁状态(Normal),此时Mark Word存对象哈希码(identity hash code)、分代年龄、是否为偏向锁等信息
- 101:偏向锁状态(Biased),第3~54位存偏向线程ID,第55~57位存Epoch,第58~61位存分代年龄,第62位为是否偏向锁标志
- 000:轻量级锁状态(Lightweight Locked),此时Mark Word保存指向栈中Lock Record的指针(即Displaced Mark Word的地址)
- 010:重量级锁状态(Heavyweight Locked),此时Mark Word保存指向对应monitor对象(ObjectMonitor)的指针
- 111:GC标记状态(如CMS使用),与锁无关,但会临时覆盖锁状态位
锁升级过程中的Mark Word变化
锁状态不是静态配置的,而是随竞争程度动态演进。JVM在运行时通过CAS操作修改Mark Word的值来完成锁的获取与升级:
安全的随机密码生成器。支持自定义长度、字符类型(大写/小写字母、数字、特殊符号),排除相似字符,批量生成。纯 Python 标准库,无需 API 密钥。
- 新建对象默认为“无锁”状态(001),若启用了偏向锁且未禁用(-XX:+UseBiasedLocking),会在第一次被线程访问时尝试设置为偏向锁(101)
- 当有其他线程竞争同一对象时,偏向锁会撤销(revoke),Mark Word恢复为无锁状态,随后进入轻量级锁流程:在当前线程栈中创建Lock Record,将对象原Mark Word复制到Lock Record中,并用CAS把Mark Word更新为指向该Lock Record的指针(000)
- 若自旋失败或竞争激烈,轻量级锁膨胀为重量级锁:JVM在堆中创建ObjectMonitor,将Mark Word更新为指向该monitor的指针(010),同时唤醒阻塞队列中的线程
如何验证Mark Word内容?
Mark Word本身不可直接读取,但可通过工具间接观察其状态:
立即学习“Java免费学习笔记(深入)”;
- 使用JOL(Java Object Layout)库打印对象内存布局:
System.out.println(ClassLayout.parseInstance(obj).toPrintable());,输出中会显示lock字段(如“0x01”表示无锁,“0x05”表示偏向锁) - 配合JVM参数如
-XX:+PrintGCDetails、-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly(需hsdis)可辅助分析锁相关汇编指令 - 注意:开启
-XX:-UseBiasedLocking后,新对象跳过偏向锁阶段,直接走轻量级锁路径
常见误区提醒
Mark Word记录的是锁的“当前状态”,不是锁的“持有者身份”本身:
- 偏向锁的线程ID存在Mark Word里,但仅在无竞争时有效;一旦发生竞争,偏向即失效,不保证原子性维护
- 轻量级锁的Lock Record在栈上,Mark Word只存指针,因此依赖栈帧生命周期;线程退出同步块时需用CAS将原Mark Word恢复
- 重量级锁下,真正管理锁逻辑的是ObjectMonitor,Mark Word退化为一个引用,不再参与加解锁逻辑

















