一、Java对象的内存占用

在HotSpot虚拟机上,一个java对象的内存占用一般包括如下几部分:
1、一个对象头部信息(包括几字节的基本元信息)
2、原始类型字段的内存占用
3、引用字段的内存占用
4、对齐字节(padding):为了让每个对象的开始地址是字节的整数倍,减少对象指针占用的比特数,对象数据后面会添加一些“无用”的字节,以实现对齐,即保证最终的字节大小是8的倍数

二、对象头

HotSpot虚拟机的对象头包含两部分信息:
1、用于存储对象自身的运行时数据,这部分数据在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit。
2、类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
(注:如果java对象是一个数组,还必须包含用于记录数组长度的数据,因为java虚拟机可以从普通java对象的元数据信息确定对象的大小,但是从数组的元数据中却无法确定数组的大小。)

java元数据类型占用字节列表:

Java 字段不对齐 导出Excel java字节对齐_Java 字段不对齐 导出Excel

三、例子

可能会认为boolean会占用一比特或者占用一个字节的第八位,但是HotSpot虚拟机会为每个Boolean字段分配一个字节的空间。
在HotSpot中,每个对象占用的内存大小是 8 字节的倍数。如果对象所需的内存大小(包括头信息和字段)不是 8 的倍数,则会向上取整到 8 的倍数。
也就是说:
1、一个空对象占用8字节
2、只有一个 boolean 字段的类实例占 16 字节:头信息占 8 字节,boolean 占 1 字节,为了对齐达到 8 的倍数会额外占用 7 个字节
3、包含 8 个 boolean 字段的实例也会占用 16 字节:头信息占用 8 字节,boolean 占用 8 字节;因为已经是 8 的倍数,不需要补充额外的数据来对齐
4、一个包含 2 个 long 字段、3 个 int 字段、1 个 boolean 字段的对象将占用40字节

  • 头信息占 8 字节
  • 2 个 long 字段占 16 字节(每个 long 字段占用 8 字节);
  • 3 个 int 字段占 12 字节(每个 int 字段占用 4 字节);
  • 1 个 boolean 字段占 1 个字节;
  • 为了对齐额外多 3 个字节(上面加起来是 37 字节,为满足对齐 8 的倍数 40)