Java 对象占用内存大小

Java 对象
HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

Java 对象头包括Mark Word,Class Metadata Address,ArrayList(数组对象)三部分。

Mark Word(32/64 bit)
HotSpot虚拟机的对象头(Object Header)包括两部分信息,第一部分用于存储对象自身的运行时数据, 如哈希值(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,这部分数据的长度在32位和64位的虚拟机(暂不考虑开启压缩指针的场景)中分别为32个和64个Bits,官方称它为“Mark Word”。

Class Metadata Address(32/64 bit)
存储该对象的Class 对象的地址,就是该对象属于那个Class。

ArrayList(32/64 bit)
存储数组的长度,如果是数组对象才会有此数据。非数组对象没有此数据。

32位系统:
对象头占用:32+32=64bit。 64bit/8=8byte。
数组对象头占用:32+32+32=96bit。 96bit/8=12byte。

64位系统:
对象头占用:64+64=128bit。128bit/8=16byte。
数组对象头占用:64+64+64=192bit。 192bit/8=24byte。

实例数据
实例数据就是,对象中的实例变量。
实例变量类型分为:基本类型和引用类型。Java 对象占用内存大小_第1张图片
对齐填充
对象在堆中分配的最新存储单位是8byte。如果存储的数据不够8byte的倍数,则对齐填充够8的倍数个字节。

最后需要注意一点就是从JDK 1.6 update14开始 64bit的jvm默认是开启了UseCompressedOops,而且这个参数也只是针对64bit的jvm有效。所以java对象占用内存的大小会小于等于我们正常计算出的对象大小。

你可能感兴趣的:(Java)