news 2026/5/7 4:02:27

synchronized内存布局图(bit 精确位置)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
synchronized内存布局图(bit 精确位置)

64位 HotSpot JDK 8下的对象头精确 bit 位布局图反编译验证示例为例


一、64位 JDK 8 对象头(Mark Word)精确 bit 位布局

以下基于HotSpot 64位 VM,默认开启指针压缩(-XX:+UseCompressedOops-XX:+UseCompressedClassPointers),此时 Mark Word 占8 字节,Klass Pointer 占4 字节,对象头共 12 字节。

Mark Word 各状态 bit 位拆解(低位在右)

1. 无锁状态(biased_lock=0,lock=01)
|--------------------------------------------------| | unused:25 | identity_hashcode:31 | age:4 | 0 | 01 | |--------------------------------------------------| bits 63-39 bits 38-8 bits 7-4 3 2-0
  • bit 0–1:锁标志位01(无锁/偏向未生效)
  • bit 2:偏向锁标记0(无锁)
  • bit 3–6:分代年龄(age)
  • bit 7–38:对象哈希码(如果已调用System.identityHashCode()
  • bit 39–63:未使用(或存 GC 元信息)

2. 偏向锁状态(biased_lock=1,lock=01)
|--------------------------------------------------------------| | thread:54 | epoch:2 | unused:1 | age:4 | 1 | 01 | |--------------------------------------------------------------| bits 63-10 bits 9-8 bit 7 bits 6-3 2 1-0
  • bit 0–1:锁标志位01
  • bit 2:偏向锁标记1(表示是偏向锁状态)
  • bit 3–6:分代年龄(age)
  • bit 7:未使用
  • bit 8–9:偏向锁 epoch(用于批量重偏向)
  • bit 10–63:持有偏向锁的线程 ID(54 bits)

3. 轻量级锁状态(lock=00)
|--------------------------------------------------| | 指向 Lock Record 的指针 | 00 | |--------------------------------------------------| bits 63-2 1-0
  • bit 0–100
  • bit 2–63:指向当前线程栈中Lock Record的指针(62 bits 可用,因为指针最后2位为0,实际存储时右移2位)

4. 重量级锁状态(lock=10)
|--------------------------------------------------| | 指向 ObjectMonitor 的指针 | 10 | |--------------------------------------------------| bits 63-2 1-0
  • bit 0–110
  • bit 2–63:指向 C++ 对象ObjectMonitor的指针

5. GC 标记(lock=11)
|--------------------------------------------------| | GC 标记信息 | 11 | |--------------------------------------------------| bits 63-2 1-0
  • bit 0–111(表示对象被 GC 标记,具体含义取决于 GC 算法)

图示总览(一个容易记忆的图表)

┌─────────────────────────────────────────────────────────────┐ │ Mark Word (64 bits) │ ├──────────────┬─────────────────────┬──────────┬─────────────┤ │ 无锁(001) │ unused:25 | hash:31 │ age:4 │ 0 │ 01 │ ├──────────────┼─────────────────────┼──────────┼─────────────┤ │ 偏向(101) │ thread:54 | ep:2 │ age:4 │ 1 │ 01 │ ├──────────────┼─────────────────────┼──────────┼─────────────┤ │ 轻量级(00) │ ptr to LockRecord (62 bits) │ 00 │ ├──────────────┼─────────────────────┼──────────┼─────────────┤ │ 重量级(10) │ ptr to ObjectMonitor (62 bits)│ 10 │ ├──────────────┼─────────────────────┼──────────┼─────────────┤ │ GC标记(11) │ GC info (62 bits) │ 11 │ └──────────────┴─────────────────────┴──────────┴─────────────┘

其中age(4 bits)表示对象在年轻代中存活次数,达到阈值 15 将晋升到老年代。


二、反编译验证示例(javap 查看 monitorenter/monitorexit)

1. 编写简单同步代码

publicclassSynchronizedDemo{privatestaticfinalObjectlock=newObject();publicstaticvoidmain(String[]args){synchronized(lock){System.out.println("Hello synchronized");}}}

2. 编译并反编译

javac SynchronizedDemo.java javap-c-vSynchronizedDemo.class

3. 关键字节码输出(截取 main 方法)

publicstaticvoidmain(java.lang.String[]);Code:0:getstatic #2// lock3:dup4:astore_15:monitorenter// <-- 进入 synchronized6:getstatic #3// System.out9:ldc #4// "Hello synchronized"11:invokevirtual #5// println14:aload_115:monitorexit// <-- 退出 synchronized16:goto2419:astore_220:aload_121:monitorexit// <-- 异常时的退出22:aload_223:athrow24:returnExceptiontable:fromtotargettype61619any
  • monitorentermonitorexit指令是 synchronized 的字节码基础。
  • 实际锁升级、对象头修改由 JVM 内部在运行时完成,字节码层面看不到锁状态。

三、JOL(Java Object Layout)验证对象头变化

JOL 是 OpenJDK 提供的工具,可以直接打印对象内存布局,直观看到 Mark Word 的变化。

1. Maven 依赖

<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.17</version></dependency>

2. 验证无锁 → 偏向锁 → 轻量锁 → 重量锁

importorg.openjdk.jol.info.ClassLayout;importorg.openjdk.jol.vm.VM;publicclassJolExample{publicstaticvoidmain(String[]args)throwsInterruptedException{// 等待偏向锁延迟过去(默认4秒)Thread.sleep(5000);Objectobj=newObject();// 无锁状态(实际是偏向未锁定,但JOL会显示为偏向锁不可用?)System.out.println("=== 刚创建,无锁 ===");System.out.println(ClassLayout.parseInstance(obj).toPrintable());// 加偏向锁(一个线程加锁)synchronized(obj){System.out.println("\n=== 偏向锁 ===");System.out.println(ClassLayout.parseInstance(obj).toPrintable());}// 另一个线程来竞争,导致升级为轻量锁(需要另外的线程,简单场景可用两个线程演示)Threadt=newThread(()->{synchronized(obj){System.out.println("\n=== 其他线程获得锁(轻量锁/重量锁)===");System.out.println(ClassLayout.parseInstance(obj).toPrintable());}});t.start();t.join();// 再main线程加锁,可能升级为重量锁(多竞争几次)for(inti=0;i<10;i++){newThread(()->{synchronized(obj){try{Thread.sleep(10);}catch(InterruptedExceptione){}}}).start();}Thread.sleep(100);synchronized(obj){System.out.println("\n=== 高竞争后,可能变为重量锁 ===");System.out.println(ClassLayout.parseInstance(obj).toPrintable());}}}

3. 输出示例(节选关键字段)

=== 刚创建,无锁 === # 运行状态(无锁): OFF SZ TYPE DESCRIPTION 0 8 (object header) 01 00 00 00 00 00 00 00 (未偏向) 8 4 (class pointer) 12 4 (padding) === 偏向锁 === # 偏向状态: 0 8 (object header) 05 30 f2 4a 19 02 00 00 (末尾 05 表示偏向锁) === 其他线程获得锁(轻量锁)=== # 轻量锁状态(末尾 00 或 f0): 0 8 (object header) a8 f4 1f 78 71 7f 00 00 (末尾 bit 为 00) === 高竞争后,重量锁 === # 重量锁状态(末尾 3a 或 ba): 0 8 (object header) 3a 0a 56 1a 00 00 00 00 (末尾 10)

注意:实际十六进制数据中,最后两个 bit(低位)是锁标志:

  • 01且第3 bit 为 0 → 无锁
  • 05(00000101) → 偏向锁(101)
  • 00f0等,最后两位 00 → 轻量锁
  • 3a(00111010)最后两位10→ 重量锁

四、如何确定当前 JVM 使用的是哪种锁?

可以通过打印系统属性或者 JVM 参数查看:

java-XX:+PrintFlagsFinal|grepBiasedLocking

结果示例:

bool UseBiasedLocking=true{product}intx BiasedLockingStartupDelay=4000{product}

若偏移锁关闭,则对象创建后直接为轻量级锁的“无锁可偏向”状态,实际不太一样,但底层仍会经历 “无锁 → 轻量锁 → 重量锁”。


五、小结

  • 精确 bit 图:上面已给出 64 位下每个状态的使用位。
  • 验证方法
    • 字节码:javap看到monitorenter/exit
    • 内存布局:JOL打印对象头十六进制,对照锁标志位判断当前锁状态。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/7 3:58:34

2026成都招牌灯箱卷王横评:5大供应商口碑排行+避坑手册

第一章 行业趋势&#xff1a;灯箱市场进入规模化整合期2026年&#xff0c;中国灯箱行业已从早期萌芽阶段迈入规模化发展新周期。根据中国广告协会公开数据显示&#xff0c;西南地区灯箱市场规模年增长率稳定在12%以上&#xff0c;其中成都招牌灯箱作为区域特色品类&#xff0c;…

作者头像 李华
网站建设 2026/5/7 3:55:01

基于OpenClaw Conversation框架构建智能对话系统:从原理到实践

1. 项目概述与核心价值最近在探索如何让AI对话系统更“接地气”&#xff0c;或者说&#xff0c;如何让一个模型不仅能理解你的指令&#xff0c;还能像朋友一样跟你聊得有来有回&#xff0c;甚至能记住你们之前聊过什么。这听起来简单&#xff0c;但背后涉及到对话状态管理、上下…

作者头像 李华
网站建设 2026/5/7 3:54:30

LinkSwift技术解析:构建跨平台网盘直链解析的工程实践

LinkSwift技术解析&#xff1a;构建跨平台网盘直链解析的工程实践 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼…

作者头像 李华
网站建设 2026/5/7 3:52:09

【YOLOv11】100、YOLOv11综合实战:从零到一构建完整的目标检测系统

昨天深夜调一个模型部署问题,摄像头画面里的小物体检测框总是飘忽不定。 盯着终端里跳动的置信度数值,突然意识到——很多问题不是出在模型本身,而是整个系统链路中某个环节的“默契度”不够。今天咱们就从头搭一套能实际跑起来的YOLOv11检测系统,把那些容易踩坑的地方逐个…

作者头像 李华
网站建设 2026/5/7 3:51:30

WAP技术解析:无线应用协议与移动互联网演进

1. WAP技术&#xff1a;无线互联网的第一次革命2000年初&#xff0c;当我第一次在诺基亚7110手机上通过WAP浏览器查看股票行情时&#xff0c;那种突破空间限制获取信息的震撼感至今难忘。作为移动互联网的早期形态&#xff0c;WAP&#xff08;Wireless Application Protocol&am…

作者头像 李华