美团面试:如何计算一个对象在内存中占多少个字节?

在分配对象的时候会有一些基本的规则,我们可以根据一些规则大致能判断出来对象大小。

在这里插入图片描述

在 Hotspot VM 中,对象在内存中的存储布局分为三个区域:

  1. 对象头(Header)
  2. 实例数据(Instance Data)
  3. 对齐填充(Padding)

对象头(Header)

对象头包括以下三部分:

  1. MarkWord:用于存储对象运行时的数据,例如 HashCode、锁状态标志、GC 分代年龄等。在 64 位操作系统下占 8 字节,32 位操作系统下占 4 字节。
  2. 元数据指针:指向对象的类元数据的指针,虚拟机通过这个指针确定该对象属于哪个类。在开启指针压缩的情况下占 4 字节,未开启时占 8 字节。
  3. 数组长度:仅在数组对象中存在,占 4 字节。非数组对象不包含这一部分。

实例数据(Instance Data)

用于存储对象中的各类字段信息,包括从父类继承而来的字段。

对齐填充(Padding)

Java 对象的大小默认按照 8 字节对齐,也就是说 Java 对象的大小必须是 8 字节的倍数。如果对象大小不足 8 字节,则进行填充以满足对齐要求。

8 字节对齐的原因

8 字节对齐并不是浪费空间资源,主要有以下原因:

  1. CPU 内存访问效率:CPU 进行内存访问时,一次寻址的指针大小是 8 字节,正好与 L1 缓存行的大小一致。如果不进行内存对齐,可能会出现跨缓存行的情况,这会导致缓存行污染,影响性能。
  2. 提高内存访问速度:内存对齐可以提高数据访问的速度,因为对齐的数据可以在一个内存访问周期内读取完毕,而未对齐的数据可能需要多个周期。

通过 8 字节对齐,可以减少 CPU 访问内存时的额外开销,从而提升整体性能。

在这里插入图片描述

由于当 obj1 对象的字段被修改后,那么 CPU 在访问 obj2 对象时,必须将其重新加载到缓存行,因此影响了程序执行效率。

也就说,8字节对齐,是为了效率的提高,以空间换时间的一种方案。固然你还能够 16 字节对齐,可是 8 字节是最优选择。

Java 对象到底占用多大内存

前面我们分析了 Java 对象到底都包含哪些东西,所以现在我们可以开始剖析一个 Java 对象到底占用多大内存。

由于现在基本都是 64 位的虚拟机,所以后面的讨论都是基于 64 位虚拟机。 首先记住公式,对象由 对象头 + 实例数据 + padding 填充字节组成,虚拟机规范要求对象所占内存必须是 8 的倍数,padding 就是干这个的。
从 JDK 8 开始,HotSpot JVM 默认开启了指针压缩(Compressed Oops)。指针压缩可以减少对象指针的大小,从而节省内存空间,提高内存访问的效率。

一个空的Java object 对象占多大内存?

一个空的对象,在开启压缩指针的情况下,占16个字节。其中Markword占8个字节、类元指针占4个字节, 对齐填充占4个字节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值