当前位置: 首页 > web >正文

Java对象中的MarkWord

一、Java对象的内存结构

每个Java对象在内存中由三部分组成(以64位JVM为例):

|---------------------------------|
|       对象头 (12-16字节)        |  → 包含Mark Word和类型指针
|---------------------------------|
|       实例数据 (不定长)          |  → 存储对象的字段值
|---------------------------------|
|       对齐填充 (0-7字节)         |  → 确保对象总大小为8的倍数
|---------------------------------|

二、Mark Word的核心作用

Mark Word是​​对象头的核心部分​​(固定8字节),用于存储对象的运行时状态,包括:

  • 🔐 ​​锁状态​​(无锁、偏向锁、轻量级锁、重量级锁)
  • 🆔 ​​哈希码​​(对象的唯一标识)
  • 🧓 ​​GC分代年龄​​(对象被垃圾回收的次数)
  • 🧵 ​​线程ID​​(持有偏向锁的线程)
  • ⏰ ​​时间戳​​(偏向锁的时效性验证)

📌 ​​关键设计​​:Mark Word像​​变色龙​​一样复用存储空间,根据对象状态动态调整内容。


三、Mark Word的结构变化(锁升级视角)

下图展示64位JVM下Mark Word在不同锁状态时的结构变化:

| 锁状态      | Mark Word结构 (64位)                          | 标志位 |
|-------------|-----------------------------------------------|--------|
| **无锁**    | 哈希码(31位) \| 分代年龄(4位) \| 0 \| **01**  | `01`   |
| **偏向锁**  | 线程ID(54位) \| Epoch(2位) \| 1 \| **01**     | `01`   |
| **轻量级锁**| 指向栈中锁记录的指针(62位) \| **00**          | `00`   |
| **重量级锁**| 指向重量级锁(Monitor)的指针(62位) \| **10**   | `10`   |
| **GC标记**  | (空) \| **11**                                | `11`   |

🔍 ​​锁升级过程​​(以线程竞争为例):
无锁 → 偏向锁(单线程反复访问)→ 轻量级锁(少量竞争,CAS自旋)→ 重量级锁(激烈竞争,线程阻塞)。


四、核心字段详解

  1. ​分代年龄 (4位)​

    • 记录对象被GC的次数(最大值15,因4位二进制最大值为1111=15
    • 达到阈值后对象从年轻代晋升到老年代。
  2. ​哈希码 (31位)​

    • 调用hashCode()后生成,延迟存储到Mark Word
    • 加锁后因空间不足,会迁移到Monitor中。
  3. ​线程ID (54位)​

    • 偏向锁状态下记录持有锁的线程ID
    • 同一线程再次加锁时直接通行(无同步开销)。

五、实战观察工具 - JOL

使用​​JOL库​​(Java Object Layout)直接打印对象内存布局:

// 添加Maven依赖
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.17</version>
</dependency>// 打印Object对象布局
public static void main(String[] args) {Object obj = new Object();System.out.println(ClassLayout.parseInstance(obj).toPrintable());
}

输出示例(无锁状态):

java.lang.Object object internals:
OFFSET  SIZE   TYPE DESCRIPTION
0     4        (object header)  01 00 00 00  # Mark Word (01表示无锁)
4     4        (object header)  00 00 00 00  # 类型指针 (压缩后4字节)
8     4        (alignment padding)          # 对齐填充
Instance size: 16 bytes

🔑 ​​锁状态验证​​:
synchronized代码块内打印对象布局,可见标志位从01变为00(轻量级锁)。


六、为什么这样设计?

  1. ​空间极致利用​

    • 通过动态复用8字节空间,避免为每种状态分配独立空间。
  2. ​性能优化​

    • 偏向锁减少无竞争时的同步开销
    • 轻量级锁用CAS避免线程阻塞。
  3. ​扩展性​

    • 标志位决定结构,未来可扩展新状态(如JDK15的ZGC标记位11)。

七、总结:Mark Word的核心角色

功能实现机制
​身份证明​存储哈希码和GC年龄
​锁管理​通过标志位切换锁状态
​线程协同​记录持有锁的线程ID
​内存优化​动态复用存储空间

💎 ​​一句话理解​​:
Mark Word是Java对象的​​智能身份证​​,既存储身份信息(哈希码/年龄),又动态反映当前状态(锁类型),以最小空间支撑JVM的高效运行。

http://www.xdnf.cn/news/14401.html

相关文章:

  • 【大厂机试题解法笔记】字符串加密
  • java 设计模式_行为型_18解释器模式
  • 【MySQL】TencentOS 安装登录MySQL
  • 【Flutter】解决小米澎湃系统迷你窗口、缩小窗口后界面空白问题
  • 电阻篇---常见作用
  • Rviz2中,在rviz和launch文件中都需要配置urdf文件,二者作用上的区别?
  • hot100 -- 13.堆系列
  • MongoDB使用安全的sha256认证
  • 【Elasticsearch】文档(二):更新
  • FPGA中的DMA技术
  • 制作微PE U盘后电脑多出300M盘符(EFI分区)无法隐藏的解决过程
  • Vue3 Pinia Store 生命周期管理
  • 前端开发面试题总结-vue2框架篇(二)
  • 国产替代新标杆|盟接之桥EDI软件让中国制造连接世界更安全、更简单、更有底气
  • AI for Science:智能科技如何重塑科学研究
  • 机器能做科学家吗?一场关于开放式科研的 AI 革命
  • 人工智能嵌入公共服务治理的风险挑战(三)
  • day31 文件的规范拆分和写法
  • 多线程与多进程技术全景对比
  • 平均数与倍数
  • 地理空间视角下的 SIR 传染病模型模拟与可视化
  • ObservedV2装饰器和Trace装饰器
  • 浏览器拨打电话 nginx代理wss (mod_cti基于FreeSWITCH)
  • 山东大学软件学院创新项目实训开发日志——第十六周
  • 【Python打卡Day40】训练与测试的规范写法 @浙大疏锦行
  • LeCun破局:大模型与人类思考的本质分野
  • 快速学习GO语言总结
  • JNDI注入入门
  • jetson nano 无法启动排查实录:使用i2c误写 EEPROM (地址 0x50)引发的修复经历
  • RT1176 QDEC引脚全解析:精准定位编码器接口资源