java 对象的存储结构和指针压缩

在HotSpot虚拟机里,对象在堆内存中的存储不惧可以划分为三个部分:

对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

下面对各部分理解:

对象头:包含了Mark Word(一定存在),元数据指针(一定存在),数组size(如果这个对象是个数组对象的话)。

实例数据:类元信息中定义的变量数据

对齐填充:可能存在的部分,同对象头一样,为了8字节对齐的无实际意义填充部分。

对待64位虚拟机来说,低于32G内存,默认开启指针压缩,那么堆中的对象是这样子的。

java 对象的存储结构和指针压缩_第1张图片

我们可以使用jol包来观察对象的存储结构,引入pom文件


    org.openjdk.jol
    jol-core
    0.10

主要使用到的方法有两个:

(1)查看对象内部信息: ClassLayout.parseInstance(obj).toPrintable()

(2)查看对象占用空间总大小:GraphLayout.parseInstance(obj).totalSize()

 

那么我们来看一下空对象会占用多大内存,按照计算,一个空的Object对象,64位虚拟机打开指针压缩(默认开启或者VM -options设置下  -XX:+UseCompressedOops开启),应该是:

Object:  markword 8bytes + class地址 4bytes + 成员变量 0bytes + 对齐填充 4bytes = 16bytes

写个main函数试试:

    public static void main(String[] args){
        Object obj = new Object();
        System.out.println(ClassLayout.parseInstance(obj).toPrintable());
    }        

我们看到的内容

可以看到我们的预想完全正确

那么关闭指针压缩,一个空对象会多大呢

Object:  markword 8bytes + class地址 8bytes + 成员变量 0bytes + 对齐填充 0bytes = 16bytes

-XX:-UseCompressedOops 关闭指针压缩

所以,开启指针压缩一定比关闭指针压缩要费空间是错误的。

指针压缩的原理:

指针不再表示对象在内存中的精确位置,而是表示偏移量。这意味着32位的指针可以引用40亿个对象,而不是40亿个字节。最终,也就是说内存增长到32GB的物理内存,也可以用32位的指针表示。也就是说,我们只需要知道JVM内存的开始位置,知道偏移量,就可以算出我想要找的实际物理位置。

 

你可能感兴趣的:(Java知识点综合)