程序员

如何计算java对象的大小?

2020-10-31  本文已影响0人  WinkTink

1. 了解对象的内存布局?

2. 每部分占用多少字节说明

2.1  对象头区域

2.1.1 对象头 Mark Word 

        在32bit系统占   4B(字节)

        在 64bit系统占 8B 

2.1.2 类型指针 (Klass pointer 对象所属的类的元信息的实例指针 instanceKlass在方法区的地址 )

        指针压缩  (默认开启)

        开启 4B  

        关闭 8B 

2.1.3 数组长度 

        如果这个对象不是数组,占0B 

        如果这个对象是数组,占4B 

         一个数组最多有多少元素 2的32次方 - 1(1B=8bit)

2.2 实例数据 

         类的非静态属性,生成对象时就是实例数据 

         对象属性大小

         boolean 1B 

          byte 1B 

          char 2B 

          short 2B 

          int 4B

          float 4B 

          double 8B 

          long 8B  

          引用类型 

                开启指针压缩 4B   

                关闭指针压缩 8B

2.3 对齐填充 

      Java中所有的对象大小都是8字节对齐 8的整数倍 16B 24B 32B 不可能是30B 如果一个对象占30B + JVM底层会补2B(对齐填充),凑成32字节,达到8字节整数倍

      对齐对齐填充补0 

      为什么要做填充?

      程序更好写 性能更高

3. 计算案例

3.1 没实例数据的对象 (16bytes)

public class CountEmptyObjectSize {

    public static void main(String[] args) {

        CountEmptyObjectSize obj = new CountEmptyObjectSize();

        System.out.println(ClassLayout.parseInstance(obj).toPrintable());

      // 8  +4 +0+ 0 +4 

    }

}

3.2 普通对象(24btyes)

public class CountObjectSize {

    int a =10;

    int b =20;

  public static void main(String[] args) {

           CountObjectSize object =new CountObjectSize();

           System.out.println(ClassLayout.parseInstance(object).toPrintable());

            // 8+4+0 +4*2 +0

    } 

}

3.3 数组对象(关闭指针压缩时,两次填充)

      开启指针压缩(32bytes)

public class CountSimpleObjectSize {

        static int[]arr = {0, 1, 2};

        public static void main(String[] args) {

              CountSimpleObjectSize test1 =new CountSimpleObjectSize();

              System.out.printf(ClassLayout.parseInstance(arr).toPrintable());

              // 8+4+4 +  + 3*4 +4(对其填充)   (开启指针压缩)

        }

}

关闭指针压缩  (40bytes)

      关闭(-XX:-UseCompressedOops) 可以关闭压缩指针

8+8+4 +4(填充) +4*3+ 4(填充)  两段填充

上一篇下一篇

猜你喜欢

热点阅读