likes
comments
collection
share

一个Java对象占用多大内存-实践篇

作者站长头像
站长
· 阅读数 3

1. 对象大小查看神器

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

jol工具是查看对象大小的神器,能查看对象大小还能查看对象头大小。这里用到的查看对象的大小

1.1 指针压缩开启-对象只包含基础数据类型

对象类:

public class ObjectBase {

    //这个对象大小应该是: 8+4+4+8+1+7=32

    private int a;

    private long b;

    private byte c;

}

测试验证代码:

public class Test1 {

    public static void main(String[] args) {
        ClassLayout layout = ClassLayout.parseClass(ObjectBase.class);
        System.out.println(layout.toPrintable());
    }
}

测试结果:

一个Java对象占用多大内存-实践篇 结果和上面的预测一样,有7byte的填充。

1.2 指针压缩开启-对象包含基础数据和引用对象

对象类:

public class ObjectBase {

    //这个对象大小应该是: 8+4+4+8+1+4+3=32

    private int a;

    private long b;

    private byte c;

    private RefObject refObject;

}
public class RefObject {

    private int a = 1;

    private short b = 2;

}

测试验证代码:

public class Test1 {

    public static void main(String[] args) {
        ClassLayout layout = ClassLayout.parseClass(ObjectBase.class);
        System.out.println(layout.toPrintable());
    }
}

测试结果:

一个Java对象占用多大内存-实践篇

1.3 指针压缩开启-数组对象

测试代码:

public class Test1 {

    public static void main(String[] args) {
        //ClassLayout layout = ClassLayout.parseClass(ObjectBase.class);
        ClassLayout layout = ClassLayout.parseInstance(new ObjectBase[10]);
        System.out.println(layout.toPrintable());
    }

}

测试结果:

一个Java对象占用多大内存-实践篇

1.4 指针压缩关闭

以3.1的代码作为测试代码,增加 -XX:-UseCompressedOops 参数,测试结果为:

一个Java对象占用多大内存-实践篇

JDK17的情况下竟然没效果。看一下JDK11

一个Java对象占用多大内存-实践篇

jdk11和预想的一样。

2. 总结

Java对象大小主要由三部分注册:对象头、对象实际数据、填充对齐字段大小三部分组成。而对象头的大小相对固定,在开启了指针压缩的情况下对象头的大小最小12,最大16字节,然后实际数据大小取决于Java对象的成员变量多少。最好就是需要多少的对齐字节。默认的情况下Java对象大小都是8的整数倍。

我是蚂蚁背大象,文章对你有帮助点赞关注我,文章有不正确的地方请您斧正留言评论~谢谢!

参考文档: