从 Java 14 开始,Project Valhala引入了 Value Type(或者称为 inline type),参考: Valhalla: https://openjdk.java.net/projects/valhalla/ , 这里不讨论 Value Type 也就是 record 类型。
首先,Java 对象在堆内存内存中结构包括:
- 类型指针: 一个指向类信息的指针,描述了对象的类型。
- 标记字(Mark Word): 一组标记,描述了对象的状态,包括对象散列码(如果有)、对象的形状(是否是数组)、锁状态、数组长度(如果标记显示这个对象是数组,描述了数组的长度)
- 对齐性填充: 所有对象都是8字节对齐的 -> 也就是说,所有对象的起始位置都是满足A(A%8==0),所以对于有的对象需要这个对齐性填充来满足这个规则。
- 域变量区域: 这个对象的域变量所占用的内存。Java域变量存在两类:原始类型(primitive type)和普通对象指针(ordinary object pointer)。
然后, Java 对象的类型信息存储于 Java 元空间之中,默认情况下(压缩类指针开启的情况下),对象头的压缩类指针指向 MetaSpace 的类空间,类空间中存储各种指针型数据,例如实现方法多态以及 virtual call 的 vtable 与 itable 保存着方法代码地址的引用指针。非类空间中存储着比较大的元数据,例如常量池,字节码,JIT 编译后的代码等等。由于编译后的代码可能非常大,以及 JVM 对于多语言支持的扩展可能动态加载很多类,所以将 MetaSpace 的类空间与非类空间区分开。