参考视频:https://www.bilibili.com/video/BV16J411h7Rd?p=75
参考博客:https://blog.csdn.net/weixin_43896929/article/details/121999131?spm=1001.2014.3001.5501
一. JAVA对象的组成
Java对象由:1. Java对象头 2.实例数据 3.对齐填充字节
Java的对象头由以下三部分组成:
- Mark Word
- Klass Word(类指针)
- array length(数组长度)
二. Java对象头
JVM中对象头分为普通非数组对象和数组对象(以32位的JVM为例)
1.普通对象
|--------------------------------------------------------------|
| Object Header (64 bits) |
|------------------------------------|-------------------------|
| Mark Word (32 bits) | Klass Word (32 bits) |
|------------------------------------|-------------------------|
2.数组对象
|---------------------------------------------------------------------------------|
| Object Header (96 bits) |
|--------------------------------|-----------------------|------------------------|
| Mark Word(32bits) | Klass Word(32bits) | array length(32bits) |
|--------------------------------|-----------------------|------------------------|
1. 对象头中的Mark Word
mark word结构如下
|------------------------------------------------------- |--------------------|
| Mark Word (32 bits) | State |
|------------------------------------------------------- |--------------------|
| identity_hashcode:25 | age:4 | biased_lock:0 | lock:01 | Normal |
|------------------------------------------------------- |--------------------|
| thread:23 | epoch:2 | age:4 | biased_lock:1 | lock:01 | Biased | // 偏向锁
|------------------------------------------------------- |--------------------|
| ptr_to_lock_record:30 | lock:00 | Lightweight Locked | // 轻量级锁
|------------------------------------------------------- |--------------------|
| ptr_to_heavyweight_monitor:30 | lock:10 | Heavyweight Locked | // 重量级锁
|------------------------------------------------------- |--------------------|
| | lock:11 | Marked for GC | // GC标记
|------------------------------------------------------- |--------------------|
各个部分的含义
lock:2位的锁状态标记位,由于希望用尽可能少的二进制位表示尽可能多的信息,所以设置了lock标记。该标记的值不同,整个mark word表示的含义不同。
biased_lock:顾明思义,为0时表示不为偏向锁,为1时表示开启偏向锁。
age:4位的Java对象年龄。在GC中,如果对象在Survivor区复制一次,年龄增加1。当对象达到设定的阈值时,将会晋升到老年代。默认情况下,并行GC的年龄阈值为15,并发GC的年龄阈值为6。由于age只有4位,所以最大值为15,这就是-XX:MaxTenuringThreshold选项最大值为15的原因。
identity_hashcode:25位的对象标识Hash码,采用延迟加载技术。调用方法System.identityHashCode()计算,并会将结果写到该对象头中。当对象被锁定时,该值会移动到管程Monitor中。
thread:持有偏向锁的线程ID。
epoch:偏向时间戳。
ptr_to_lock_record:指向栈中锁记录的指针。
ptr_to_heavyweight_monitor:指向管程Monitor的指针
2. 对象头中的Klass Word
用于指向对象类型的指针。
3. 对象头中的array length
数组对象才有的存放数组长度的空间,这部分数据的长度也随着JVM架构的不同而不同:32位的JVM上,长度为32位;64位JVM则为64位。64位JVM如果开启+UseCompressedOops选项,该区域长度也将由64位压缩至32位。