美文网首页
如何估算一个对象的大小

如何估算一个对象的大小

作者: 农民工进城 | 来源:发表于2021-06-27 20:32 被阅读0次

    如何估算一个对象的大小?
    为什么突然会想起这个话题,主要是因为在excel对象等导入导出,或者从数据库中查询出较多的对象时,预估下所占内存的大小,预估风险。

    一、Java对象内存布局

    要想预估java对象的大小,首先要明确对象内存结构是由哪几部分组成。
    一个Java对象主要包括:对象头(Header),实例数据(Instance Data),对齐填充(Padding)。
    如下图:


    对象内存结构.png

    查看是否开启压缩

    java -XX:+PrintCommandLineFlags -version
    
    image.png
    所以说默认是开启压缩的

    当然也可以通过代码,获取一个对象的布局信息。
    引入jol 的 maven坐标

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

    执行以下代码:

        public static void main(String[] args) {
            User user = new User();
            user.setAge(18);
            user.setName("zhaosc");
            System.out.println(ClassLayout.parseInstance(user).toPrintable());
        }
    
    image.png

    添加-XX:-UseCompressedOops -XX:-UseCompressedClassPointers参数之后,即去掉压缩,执行。

    执行结果如下:


    image.png

    其中:

    • mark:代表自身运行时的数据(Mark Word),8byte
    • class:代表类型指针(Class Pointer),8byte
    • age,name为实例数据,12byte
    • padding:对齐填充, 4byte

    既然知道了Java对象内存布局结果,那么如何估算一个对象的大小呢?
    对象大小=对象头+实例数+对齐填充
    所以关键在于实例数据的计算。

    二、实例数据计算

    2.1 基本类型的计算

    一个Java类的属性值,可能是基本类型或引用类型两种,所以先看简单的基本类型所占内存大小

    类型 二进制位数 bytes
    boolean 1 1
    byte 8 1
    char 16 2
    short 16 2
    Int 32 4
    long 64 8
    float 32 4
    double 64 8
    引用类型指针 64或32 在32位系统上每个占用4bytes;在64位系统上每个占用8bytes,开启指针压缩后占用4个
    2.2引用类型的计算

    引用类型的计算相对于基本类型的计算来说,比较麻烦。
    大致思路是:将引用类型,转换为基本类型,一个引用指针占用4个字节,对象头占用12个字节(因为默认开启压缩),如果数组,再加上4个字节的数组长度,不是8的倍数,对齐补充

    • java.lang.Integer
      它是int的包装类型的包装类型,所以Integer长度为:头(8+4)+ int(4) = 16字节。
      其他Long、Double等类似。

    • java.lang.String
      String="zhaosc";
      它是得底层是char数组结构。

      image.png

      String类型:头部(8+4)+int(4)+指向char[]对象的引用类型(4)+padding(4)=24字节
      char[]类型:头部(8+4)+数组长度(4)+“zhaosc”(2*6)+padding(4)=32字节
      因此,它的总占用空间为32+24=56字节,56*8=448bit

    • 自定义类 com.zhaosc.User

    public class User {
        private String name;
        private int age;
    }
    

    还是以

    User user = new User();
    user.setAge(18);
    user.setName("zhaosc");
    

    User类型:头部(8+4)+int(4)+String的引用类型(4)+padding(4)=24字节
    String类型:头部(8+4)+int(4)+指向char[]对象的引用类型(4)+padding(4)=24字节
    char[]类型:头部(8+4)+数组长度(4)+“zhaosc”(26)+padding(4)=32字节
    所以一共是24+24+32=80字节,80
    8=640bit

    相关文章

      网友评论

          本文标题:如何估算一个对象的大小

          本文链接:https://www.haomeiwen.com/subject/ysptultx.html