displaced mark word 是轻量级锁中存于线程栈帧 lock record 首字段的原始 mark word 快照,仅用于解锁时 cas 写回以验证并恢复对象头状态,不参与竞争判断,也不携带锁标识或线程信息。

Displaced Mark Word 是轻量级锁机制中一个关键但容易被忽略的“快照”字段,它的作用不是参与竞争判断,而是为加锁和解锁提供原子性依据;它不存于堆或对象头里,而是严格存储在线程栈帧内的 Lock Record 结构中。
它是解锁时恢复对象状态的唯一依据
当线程尝试获取轻量级锁时,JVM 先读取对象当前的 Mark Word(此时处于无锁状态,标志位为 01),并把完整值拷贝到本线程栈帧里的 Lock Record 中,这个拷贝就叫 Displaced Mark Word。它不是临时标记,也不是计算中间值,而是解锁时必须原样写回对象头的“原始快照”。
- 如果解锁时 CAS 成功把 Displaced Mark Word 写回对象头,说明整个同步期间没有其他线程介入,轻量级锁路径干净结束
- 如果写回失败(比如对象头已被改写为指向 ObjectMonitor 的指针),说明锁已升级为重量级,此时需交由 monitor 机制处理解锁
- 这个值一旦被覆盖或丢失,就无法安全还原对象头,会导致锁状态错乱
它只存在于当前线程的栈帧 Lock Record 里
Lock Record 是 JVM 在当前线程执行同步块前,在其栈帧中动态分配的一小块私有空间,完全脱离堆内存和共享区域。Displaced Mark Word 就存放在这个结构体的第一个字段位置,属于线程独占、生命周期与方法调用一致的局部数据。
- 不会被 GC 管理,方法退出时栈帧自动销毁,Lock Record 连同 Displaced Mark Word 一并消失
- 重入时会连续分配多个 Lock Record,每个都带自己的 Displaced Mark Word(首次为真实拷贝,后续为 null)
- 它不参与任何锁竞争逻辑,也不影响 CAS 判断条件本身,但决定了 CAS 是否能“回退”成功
它和 CAS 操作构成乐观并发控制的闭环
轻量级锁本质是乐观策略:先假设无竞争,拷贝当前状态(Displaced Mark Word),再尝试用 CAS 把对象头替换成指向 Lock Record 的指针。这两步必须配套——拷贝是 CAS 的前提,CAS 是拷贝价值的体现。
- CAS 失败不等于拷贝无效,而是说明“拷贝那一刻的状态”已被其他线程改变,此时需自旋或升级
- 若拷贝后立刻有别的线程抢先完成 CAS,本线程的 CAS 就会失败,自然进入后续流程
- 正因为有这份快照,JVM 才能在解锁时验证“是否仍处在轻量级锁语义下”,而不是盲目覆盖对象头
它不是锁标识,也不决定锁状态
很多人误以为 Displaced Mark Word 里存着锁标志位或线程 ID,其实它只保存加锁前对象头的原始内容(可能是哈希码、分代年龄等)。真正标识轻量级锁的是对象头中被 CAS 写入的 Lock Record 地址 + 标志位 00。
- 它本身不携带线程信息,也不参与偏向锁/重量级锁的判别逻辑
- 它的存在意义纯粹是支撑“原子性恢复”:加锁时读出,解锁时写回,形成一次封闭操作
- 即使锁重入多次,只有第一个 Lock Record 的 Displaced Mark Word 是有效快照,其余为空(null)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











