Java对象大小

一个Java对象的大小包括下面三个部分
1. 对象头(Header)
2. 实例数据(Instance Data)
3. 对齐填充(Padding)

对象头(Header)

对象头在32位系统上占用8bytes,在64位系统上占用16bytes

实例数据(Instance data)

Java中原生类型(Primitive Type)的内存占用情况如下:

Primitive Type Memory Required(bytes)
boolean 1
byte 1
short 2
char 2
int 4
long 8
float 4
double 8

引用类型(Reference)在32位系统上占用4bytes,在64为系统上占用8bytes。(可以类比于C++中的指针类型)

对齐填充(Padding)

HotSpot中为8字节对齐填充:

(对象头 + 实例数据 + padding)%8等于0并且 0 <= padding < 8

指针压缩

可以使用命令-XX:+UseCompressedOops开启指针压缩,JDK1.6默认开启压缩。

  1. 对对象头的影响

    对于64位机器,开启指针压缩后对象头占用字节数由 16bytes变成了12bytes

  2. 对引用类型(Reference)的影响

    对于64位机器,开启指针压缩之后,引用类型占用内存数由 8bytes变成4bytes

static class Padding {
    int a;
    Object object;
}

对于Padding类对象,在64位机器上,开启指针压缩前占用内存大小为

对象头大小: 16 bytes
a的大小:4bytes
Object引用:8bytes
padding大小:4bytes((16+4+8)%8)

所以占用总字节数为16+4+8+4=32bytes

开启指针压缩后的字节大小为

对象头大小:12bytes
a的大小:4bytes
Object引用的大小:4bytes
padding大小:4bytes((12+4+4)%8)

所以占用总字节数为12+4+4+4=24bytes

数组对象

64位机器上,数组对象的对象头占用字节数为24个字节,启用指针压缩后占用16个字节

也就是说,对于new Integer[0],开启指针压缩前占用内存大小为24bytes,开启指针压缩后的字节数为16bytes

对于new Integer[3],开启指针压缩前占用内存数为

对象头:24bytes
3个Integer引用:3*8=24bytes
padding:0bytes

所以总字节数为:24+24=48bytes.

开启指针压缩后的字节数为

对象头:16bytes
3个Integer引用:3*4=12bytes
padding大小:4bytes((16+12(%8)

所以总字节数为:16+12+4=32bytes

参考来源

2017-05-30 14:0544