一个Java对象的大小怎么计算?

一个Java对象的大小怎么计算?

对象头+实例数据+对其填充

对象头

  1. MarkWord:用于存储对象运行时的数据,如hashCode、锁状态标志、GC分代年龄等。64位操作系统占8字节,32位操作系统占4字节。
  2. 对象元数据指针(kclass):对象指向类的指针,虚拟机通过这个指针来确定这个对象是哪一个类的实例。开启压缩指针占4字节,未开启占8字节。
  3. 数组长度:只有数组对象才有,占4字节。

实例数据

实例数据可能包括两种:

  1. 8种基本数据类型

    类型 占用空间
    boolean 1
    byte 1
    char 2
    short 2
    int 4
    float 4
    long 8
    double 8
    Reference 4
  2. 对象

对其填充(Padding)

Java对象内存起始地址必须为8的整数倍,即Java对象大小必须为8的整数倍。当对象头+实例数据大小不为8的整数倍时,将会使用对其填充。

如64位,开启压缩指针的虚拟机上new Object()实际大小:

Mark Word(8B) + kclass(4B) + Padding(4B) = 16B

例子

  1. // Mark Word(8B) + kclass(4B) + i(4B) = 16B
    public class Object1{
        private int i;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    2. ```java
    // Mark Word(8B) + kclass(4B) + i(4B) + j(4B) + s(4B) + b(1B) + c(2B) + Padding(5B) = 32B
    public class ObjectSizeTest {
    private int i;
    private int j;
    private String s;
    private boolean b;
    private char c;
    }
  2. // HotSpot创建的对象的字段会默认按从长到短,引用排最后排序:long/double --> int/float --> short/char --> byte/boolean -->Reference
    //Mark Word(8B) + kclass(4B) + i1(4B) + i2(4B) + b1(1B) + b2(1B) + b3(1B) + Padding(1B) + s(4B) + obj(4B) = 32B
    public class ObjectSizeTest {
        private String s; // 4
        private int i1; // 4
        private byte b1; // 1
        private byte b2; // 1
        private int i2;// 4
        private Object obj; //4
        private byte b3;  // 1
    }
    
请作者喝瓶肥宅快乐水