一个Java对象的大小怎么计算?
对象头+实例数据+对其填充
对象头
- MarkWord:用于存储对象运行时的数据,如hashCode、锁状态标志、GC分代年龄等。64位操作系统占8字节,32位操作系统占4字节。
- 对象元数据指针(kclass):对象指向类的指针,虚拟机通过这个指针来确定这个对象是哪一个类的实例。开启压缩指针占4字节,未开启占8字节。
- 数组长度:只有数组对象才有,占4字节。
实例数据
实例数据可能包括两种:
8种基本数据类型
类型 占用空间 boolean 1 byte 1 char 2 short 2 int 4 float 4 long 8 double 8 Reference 4 对象
对其填充(Padding)
Java对象内存起始地址必须为8的整数倍,即Java对象大小必须为8的整数倍。当对象头+实例数据大小不为8的整数倍时,将会使用对其填充。
如64位,开启压缩指针的虚拟机上new Object()实际大小:
Mark Word(8B) + kclass(4B) + Padding(4B) = 16B
例子
// 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;
}// 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 }