前言
作为小白,关于Java对象的大小还停留在 8种基本类型和其包装类占用几个字节的
阶段。最近,突然发现Java对象的内存大小似乎不这么简单,就想暂且写点东西,记录一下新知识。
Java对象内存结构
总体上,提到java对象内存大小,主要分为 数组类型和非数组类型 两大类来探究。
就如同下图一样,所有的java对象一般包括 对象头(Header),实例数据(Instance data),对齐填充(padding)三部分,其中padding根据需要而存在。
不同的操作系统,其对象头的各部分大小如下:
32位操作系统
区域 | 大小(B) |
---|---|
klass | 4 |
mark | 4 |
数组长度 | 4 |
64位操作系统(指针无压缩)
区域 | 大小(B) |
---|---|
klass | 8 |
mark | 8 |
数组长度 | 4 |
64位操作系统(指针有压缩)
区域 | 大小(B) |
---|---|
klass | 4 |
mark | 8 |
数组长度 | 4 |
Java对象大小的计算公式
根据上一小节,我们可知:
Java对象大小=对象头(klass+mark+ 数组长度)+实例数据+对齐填充区
再结合一个原则,即对象属性按照 “long/double(8B) –> int/float(4B) –> short/char(2B) –> byte/boolean(1B) –> reference” 排序,我们可得出万能公式
Java对象大小=klass+mark+array_length+实例数据(字段排序且加补齐填充)
64位操作系统实例:
public class UserVo {
private String name;//4
private int id;//4
private double money;//8
private byte health;//1
private boolean isGirl;//1
private short age;//2
}
@Test
public void testaa() {
UserVo userVo = new