根据java虚拟机规范对堆(Heap)内存的描述,所有的实例对象都在堆上分配内存。对于一个实例对象而言,其本身的内在结构也是有描述方式的,也就是接下来提到的对象内存布局。
对象内存布局
一个java对象在内存中包括对象头
,实例数据
和对齐
三个部分。
对象头
对象头包括三部分:标记位(Mark word)和类指针(Class pointer),数组长度(Length)
标记位(Mark word):包含一系列的标记位信息,比如锁标识为信息,在内存中占8字节。
类指针(Class pointer):用来指向对象对应的Class对象的地址。默认启动指针压缩,占4字节;关闭指针压缩,占8字节。
数组长度(Length):如果是数组对象,对象头还包括一个保存数组长度的空间,占4字节。
实例数据
对象实例数据包含了对象的所有成员变量,其大小由各个成员变量的大小决定。同Class pointer部分一样,对于引用类型,默认启动指针压缩,占4字节;关闭指针压缩,占8字节。
对齐填充
Java对象占用空间是8字节对齐的,即所有Java对象占用bytes数必须是8的倍数。对齐填充部分要补齐前面的内存为8字节的整数倍数。
举例
Object o = new Object();在内存中占有多少字节?
Mark word 8字节,因为java默认开启了指针压缩,class pointer 4字节,Padding 4字节,因此对象在内存中占有16字节的空间。
如果没有开启指针压缩,class pointer 8字节,padding 0字节,对象在内存中占有16字节的空间。