「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战」。
Java对象头
synchronized用的锁是存在java对象头里的。HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding),如果对象是数组类型,则虚拟机用3个字宽储存对象头,如果对象是非数组类型,则用2个字节储存对象头。由于Java面向对象的思想,在JVM中需要大量存储对象,存储时为了实现一些额外的功能,需要在对象中添加一些标记字段用于增强对象功能,这些标记字段组成了对象头。
PS:字宽的长度和处理器位数有关。32位处理器1字宽等于4字节,64位处理器1字宽等于8字节。
| 长度 | 内容 | 说明 |
|---|---|---|
| 32/64bit | Mark Word | 储存对象的hashCode或者锁信息 |
| 32/64bit | Class Metadara Address | 存储到对象类型数据的指针 |
| 32/64bit | Array length | 数组的长度(如果该对象为数组类型) |
Mark Work里默认存储对象的HashCode、分代年龄和锁标记位。HotSpot虚拟机的对象头(Object Header)包括两部分信息,第一部分用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,这部分数据的长度在32位和64位的虚拟机(暂不考虑开启压缩指针的场景)中分别为32个和64个Bits,官方称它为“Mark Word”。
Mark Word的默认存储结构如图(32位)
| 锁状态 | 25bit | 4bit | 1bit是否为偏向锁 | 2bit锁标志位 |
|---|---|---|---|---|
| 无锁状态 | 对象的hashCode | 对象分代年龄 | 0 | 01 |
Mark Word 可能会变化为存储以下4数据
Mark Word在运行期间储存的数据会随着锁标志位的变化而变化。
如果处理器是64位