Java中盒装基元的存储成本是多少?

Java中的java.lang.Integerjava.lang.Character这样的盒装原语有多大(以字节为单位)?

int是4个字节,典型的指针也是4个字节(如果没有被JVM压缩)。 因此,整数(没有缓存)的成本是4 bytes + 4 bytes = 8 bytes ? 盒子对象中是否还有其他隐藏字段或者对象产生的额外开销(即,我不知道对象的一般成本是多少?)。

我对缓存问题不感兴趣。 我知道JVM会缓存一定范围内的整数。

可以重新解释这个问题:用于盒装值与原始值的内存量相乘的最大因子是多少?

编辑:我明白存在JVM的多个实现。 典型的32位HotSpot实现的典型成本是多少?

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

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

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

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

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

引用的大小显然不会影响对象本身的大小,除非它引用了其他对象,而不是简单的int包装器。 如果愿意的话,对于64位JVM,在现代JVM上使用CompressedOops (否则为8byte),对于32位为4byte,对于堆<= 32gb,我们有4byte。

[1]感兴趣的人可以查看share/vm/oops/oop.hpp

它不止于此。

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

似乎还存在VM实现差异。 确保这一点的最好方法是在分析器中将其拉出来。

我的(超级SWAG)估计会是。 对象引用16字节(64位JVM)类引用16字节原始值4字节(假设为int。)总计。 36个字节。

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

我知道这并没有完全回答你关于盒装原语的存储成本的问题,但我从你的问题中感觉到你在质疑你是否有必要使用它们。

以下是Joshua Bloch的Effective Java(第2版)的摘录,可以帮助您做出决定:

"So when should you use boxed primitives? They have several legitimate uses. The first is as elements, keys, and values in collections. You can't put primitives in collections, so you're forced to use boxed primitives. This is a special case of a more general one. You must use boxed primitives as type parameters in parame- terized types (Chapter 5), because the language does not permit you to use primi- tives. For example, you cannot declare a variable to be of type Thread- Local, so you must use ThreadLocal instead. Finally, you must use boxed primitives when making reflective method invocations (Item 53).

In summary, use primitives in preference to boxed primitives whenever you have the choice. Primitive types are simpler and faster. If you must use boxed primitives, be careful! Autoboxing reduces the verbosity, but not the danger, of using boxed primitives. When your program compares two boxed primitives with the == operator, it does an identity comparison, which is almost certainly not what you want. When your program does mixed-type computations involving boxed and unboxed primitives, it does unboxing, and when your program does unboxing, it can throw a NullPointerException. Finally, when your program boxes primitive values, it can result in costly and unnecessary object creations."

希望有所帮助。