Java 中盒装原语的存储成本是多少?

2022-09-03 02:40:33

盒装基元与 Java 或 Java 中的一样大(以字节为单位)有多大?java.lang.Integerjava.lang.Character

An 是 4 个字节,典型的指针也是 4 个字节(如果 JVM 未压缩)。整数(不缓存)的成本是否如此?box-object中是否有任何更多的隐藏字段或与对象相关的额外开销(即,我不知道的对象是否有一般成本?)。int4 bytes + 4 bytes = 8 bytes

我对缓存问题不感兴趣。我知道某个范围内的整数由JVM缓存。

人们可以改写这个问题:与基元值相比,用于盒装值的内存量乘以的最大系数是多少?

编辑:我确实知道JVM存在多种实现。典型的 32 位 HotSpot 实现的典型成本是多少?


答案 1

这是实现定义的,因此没有具体的答案。但是我应该能够为Hotspot回答它。

您需要知道的是:热点始终在8字节边界上对齐对象。此外,每个对象都有2个单词的开销。[1]

如果我们把这个放在一起,我们得到:

32 位 VM:4 字节整数 + 2 字对象标头 = 12 字节。这不是 8 的倍数,因此 1 个整数的成本是 8 的下一个倍数:16 字节。

64 位 VM:4 字节整数 + 2 个字 = 20 字节。再次向上舍入:24 字节大小。

引用的大小显然不会影响对象本身的大小,除非它具有对其他对象的引用,而对于简单的int包装器而言并非如此。如果是这样的话,对于32位,我们将有4个字节的参考,对于堆<= 32gb,对于64位JVM,我们将有4个字节(否则为8字节)。CompressedOops

[1] 有兴趣的人可以在share/vm/oops/oop.hpp


答案 2

不仅如此。

每个对象引用都有额外的开销,例如类引用。不仅如此,您的4字节指针也不是很准确。它是一个引用,所以它是一个ID加一个指针,如果你在64位JVM上,这个指针可能是8个字节。

似乎还存在 VM 实现差异。确定这一点的最佳方法是在探查器中将其拉起。

我(超级SWAG)的估计是。对象引用 16 字节(64 位 JVM) 类引用 16 字节基元值 4 字节(假设 int.)总。36 字节。

编辑:现在您指定32位JVM,使用上面的相同数学,我的SWAG将是20字节。