java对象头大小固定为16字节,mark word通过位域复用实现锁状态、哈希值等动态存储,哈希丢失是可控权衡而非缺陷,应避免临时对象锁和未重写hashcode的对象作concurrenthashmap键。

Java 中对象头大小是固定的,64 位 JVM 默认为 16 字节(8 字节 Mark Word + 8 字节类型指针),其中锁标记位并不单独占位,而是与哈希值、GC 年龄、偏向线程 ID 等动态复用 Mark Word 的同一块内存。冲突不是“需要解决”的 Bug,而是 JVM 的主动设计取舍——空间优先,状态驱动。
Mark Word 是位域复用,不是字段并存
它本质是一组紧凑的比特位布局,没有“同时存哈希和锁”的需求。不同生命周期阶段,JVM 按需解释这 64 位:
- 无锁且未计算哈希:低位为 01,高位存分代年龄或预留位
- 无锁且已调用
hashCode():低位仍为 01,高位存哈希值(31 或 61 位) - 进入轻量级锁:低位变为 00,高位覆盖为栈中 Lock Record 地址,原哈希值被丢弃
- 升级为重量级锁:低位变为 10,高位存 ObjectMonitor* 指针
哈希值丢失不是缺陷,是可控权衡
一旦对象被加锁,哈希值让位于更紧急的同步元数据。若业务依赖稳定身份哈希,不能靠运行时自动填充:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 手动缓存到
final int cachedHash = System.identityHashCode(this); - 避免将未重写
hashCode()的普通对象用作ConcurrentHashMap的 key - 禁用偏向锁(
-XX:-UseBiasedLocking)可减少哈希反复覆盖场景
真正要规避的是物理竞争,不是逻辑冲突
多个线程争抢修改同一对象的 Mark Word,本质是在争抢 CPU 缓存行中这 8 字节的 CAS 权限。缓解方式聚焦在对象使用模式上:
- 不复用临时对象做锁(如
new Object()),改用语义明确、生命周期匹配的锁实例 - 对高频访问对象,考虑无锁结构(
AtomicInteger、StampedLock分段读写) - 通过
jol-cli观察实际布局,确认锁升级路径是否符合预期,而非凭空假设
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










