Java中的java.lang.Integer
或java.lang.Character
这样的盒装原语有多大(以字节为单位)?
int
是4个字节,典型的指针也是4个字节(如果没有被JVM压缩)。因此4 bytes + 4 bytes = 8 bytes
是整数(没有缓存)的成本吗?盒子对象中是否还有隐藏的字段或者对象产生的额外开销(即,我不知道对象的一般成本是什么?)。
我对缓存问题不感兴趣。我知道JVM会缓存一定范围内的整数。
可以重新解释一个问题:用于盒装值与原始值的内存量相乘的最大因子是多少?
编辑:我确实知道存在多个JVM实现。典型的32位HotSpot实现的典型成本是多少?
答案 0 :(得分:7)
这是实现定义的,所以没有具体的答案。但我应该能够为Hotspot回答它。
您需要知道的是:Hotspot始终在8字节边界上对齐对象。此外,每个对象有2个字开销。 [1]
如果我们把它放在一起,我们得到:
32位VM:4字节整数+ 2字对象标头= 12字节。这不是8的倍数,因此1个整数的成本是8:16byte的下一个倍数。
64位VM:4字节整数+2字= 20字节。再次回合:24字节大小。
引用的大小显然不会影响对象本身的大小,除非它引用了其他对象,而不是简单的int包装器。如果是这样的话,对于64位JVM,我们在32位时为每个引用提供4byte,在现代JVM上为CompressedOops
提供4byte< = 32gb(8字节)。
[1]感兴趣的人可以查看share/vm/oops/oop.hpp
答案 1 :(得分:1)
不止于此。
每个对象引用都有额外的开销,例如Class引用。不仅如此,您的4字节指针还不太准确。它是一个引用,所以它是一个ID加一个指针,如果你在64位JVM上,那么指针可能是8个字节。
似乎还存在VM实施差异。确保这一点的最佳方法是在分析器中将其拉出来。
我的(超级SWAG)估计会是。 对象引用16字节(64位JVM) 类引用16个字节 原始值4个字节(假设为int。) 总。 36个字节。
编辑:既然您指定了32位JVM,我的SWAG将是20字节,使用相同的数学运算。
答案 2 :(得分:0)
我知道这并没有完全回答你关于盒装原语的存储成本的问题,但我从你的问题中感觉到你在质疑你是否有必要使用它们。
这是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<int>, so you must use ThreadLocal<Integer> 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."
希望有所帮助。
答案 3 :(得分:0)
这些答案的一个非常小的增加是盒装基元发生了一些重复数据删除。例如,Integer::valueOf(int)
使用java.lang.IntegerCache
,它使用值在-128..127
范围内的Integer实例。因此,您已经在上面提到了盒装对象的大小,但是并不是每个对象都是单独的对象。