多线程源码学习-对象内存布局

301 阅读1分钟

在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(header)、示例数据(Instance Data)、对其填充(Padding)

image.png

  • 对象头

对象头=对象标记(Mark word)+类型指针(Class Pointer)

hg.openjdk.java.net/jdk8u/jdk8u…

openjdk.java.net/groups/hots…

image.png

image.png

对象标记(Mark word)

1、对象的hashcode

2、GC标记

3、GC次数

4、同步锁标记

5、偏向锁持有者

image.png

在64位系统中,Mark Word占了8个字节,类型指针占了8个字节,一共16个字节。

hg.openjdk.java.net/jdk8u/jdk8u…

image.png

微信图片_20211008162940.png

GC年龄采用4bit,最大为15。如果修改JVM参数-XX:MaxTenuringThreashold=16会报错。

image.png

类型指针(Class Pointer)

指向方法区中对应的Class。

  • 实例数据

存放类的属性(Field)数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度,这部分内存按4字节对齐。

  • 对齐填充

确保总字节大小是8的整数倍

  • 验证

无实例数据
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>
public class ObjectHeadDemo {
    public static void main(String[] args) {
        Object o=new Object();
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
    }
}

image.png

有实例数据
public class ObjectHeadDemo {
    public static void main(String[] args) {
        System.out.println(ClassLayout.parseInstance(new test()).toPrintable());
    }
}

class test{
     int i=25;
     boolean f=true;
}

image.png

类型指针压缩

JVM的尾参数命令(查看JVM启动时的参数) -XX:+PrintCommandLineFlags -version

取消类型指针压缩 -XX:-UseCompressedClassPointers

查看Object类(取消类型指针压缩),可以看到没有使用对齐填充。

image.png