mark word的变化体现jvm锁升级机制:无锁→偏向锁→轻量级锁→重量级锁,其64位结构中低3位标识锁状态,其余位按状态存储哈希码、线程id、lock record或objectmonitor指针。

Java中synchronized锁升级时,Mark Word的变化是理解JVM锁优化机制的核心。它不直接暴露给开发者,但深刻影响性能——从无锁到偏向锁、轻量级锁、重量级锁的演进,本质就是Mark Word中存储信息的动态重解释。
Mark Word结构与关键位域
在64位HotSpot JVM(开启指针压缩)中,Mark Word占8字节(64位),其中低3位(bit 0–2)为锁状态标志位,决定当前锁模式;其余位根据锁状态存放不同内容:
- 无锁状态:存储对象哈希码(未计算时为0)、分代年龄、是否为偏向锁(第3位)等
- 偏向锁:第3位为1,低54位存偏向线程ID,后2位仍为锁标志(01)
- 轻量级锁:标志位为00,剩余62位存指向栈中Lock Record的指针
- 重量级锁:标志位为10,剩余62位存指向ObjectMonitor的指针
锁升级触发条件与Mark Word更新时机
锁升级不是主动“升级”,而是竞争发生时JVM对Mark Word的重新解读和写入:
使用tbot机器ID身份文件配合tsh CLI,通过Teleport访问控制SSH登录托管主机或执行远程命令。
- 偏向锁启用时(默认开启),新对象创建后Mark Word初始化为偏向状态(thread ID=0,epoch=0)
- 首次加锁:若线程ID匹配或为匿名偏向,CAS将当前线程ID写入Mark Word;失败则尝试撤销偏向
- 有其他线程竞争偏向锁:触发偏向撤销(需stop-the-world),Mark Word恢复为无锁状态,随后竞争者走轻量级锁路径
- 轻量级锁膨胀:多个线程自旋失败后,JVM将Mark Word更新为重量级锁格式,并唤醒阻塞队列中的线程
如何观察Mark Word变化
不能直接读取,但可通过工具间接验证:
- 使用jol(Java Object Layout):调用
ClassLayout.parseInstance(obj).toPrintable()输出内存布局,含Mark Word十六进制值 - 配合JVM参数:
-XX:+PrintBiasedLockingStatistics -XX:+TraceBiasedLocking查看偏向锁统计与撤销日志 - 注意:开启
-XX:+UseCompressedOops(默认)时,Mark Word结构与未压缩不同,分析需对应
常见误区与注意事项
Mark Word变化背后有隐含约束,容易误判:
- 偏向锁撤销不等于立即升级为重量级锁——通常先回到无锁态,再按竞争情况走轻量或重量路径
- GC可能修改Mark Word:如CMS或ZGC在并发标记阶段会临时设置特定位,非锁相关变更
- 锁降级不存在:JVM只支持单向升级(偏向→轻量→重量),不会因竞争减少而自动降级
- 对象头大小依赖JVM配置:开启压缩类指针(-XX:+UseCompressedClassPointers)不影响Mark Word,但影响Klass Word位置
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










