对象头
这里不讲对象头是个什么货色,感兴趣的同学能够看我的其它文章。对象头的大小个别和零碎的位数无关,也和启动参数 UseCompressedOops 无关:
32 位零碎,占用 8 字节
64 位零碎,开启 UseCompressedOops 时,占用 12 字节,否则是 16 字节
实例数据
原生类型的内存占用状况如下:
boolean 1 个字节
byte 1 个字节
short 2 个字节
char 2 个字节
int 4 个字节
float 4 个字节
long 8 个字节
double 8 个字节
援用类型的内存占用和零碎位数以及启动参数 UseCompressedOops 无关
32 位零碎占 4 字节
64 位零碎,开启 UseCompressedOops 时,占用 4 字节,否则是 8 字节
对齐填充
在 Hotspot 中,为了更加容易的治理内存,个别会应用 8 字节进行对齐。
意思是每次调配的内存大小肯定是 8 的倍数,如果对象头 + 实例数据的值不是 8 的倍数,那么会从新计算一个较大值,进行调配。
后果
有了对象各局部的内存占用大小,能够很轻松的计算出 ABCD 各对象在 64 位零碎,且开启 UseCompressedOops 参数时的大小。
A 对象只蕴含一个对象头,大小占 12 字节,不是 8 的倍数,须要 4 字节进行填充,一共占 16 字节
B 对象蕴含一个对象头和 int 类型,12+4=16,正好是 8 的倍数,不须要填充。
C 对象蕴含一个对象头和 long 类型,12+8=20,不是 8 的倍数,须要 4 个字节进行填充,占 24 字节
D 对象蕴含一个对象头和援用类型,12+4=16,正好是 8 的倍数,不须要填充。
能够得出,VisualVM 的显示后果有点问题,次要因为以下两点: