What is the storage cost for a boxed primitive in Java?

别等时光非礼了梦想. 提交于 2019-11-29 01:42:02

This is implementation defined, so there's no specific answer. But I should be able to answer it for Hotspot.

What you need to know is: Hotspot always aligns objects on 8byte boundaries. Furthermore there are 2 words overhead for each and every object. [1]

If we put this together we get:

32bit VM: 4byte integer + 2 words object header = 12bytes. That's no multiple of 8 so as a result the cost for 1 integer is the next multiple of 8: 16byte.

64bit VM: 4byte integer + 2 words = 20bytes. Rounding up again: 24byte size.

The size of a reference obviously does not play into the size of an object itself, except if it has references to other objects which isn't the case for a simple int wrapper. If it would, we'd have 4byte per reference for 32bit and 4byte for heaps <= 32gb with CompressedOops on modern JVMs (otherwise 8byte) for 64bit JVMs.

[1] Interested people can look at the code in share/vm/oops/oop.hpp

It's more than that.

Every object reference has additional overhead, such as a Class reference. Not only that, your 4-byte pointer isn't quite accurate. It's a reference, so it's an ID plus a pointer, AND that pointer may be 8 bytes if you are on a 64 bit JVM.

There also appear to be VM implementation differences. Best way to be sure on this would be to pull it up in a profiler.

My (Super SWAG) estimate would be. Object reference 16 bytes (64 bit JVM) Class reference 16 bytes primitive value 4 bytes (Assuming int.) Total. 36 bytes.

EDIT: Now that your specify 32-bit JVM my SWAG would be 20 bytes using same math above.

I know this doesn't exactly answer your question on the storage cost of boxed primitives, but I sense from your question that you are questioning whether or not your use of them is warranted.

Here is an excerpt from Effective Java (2nd Edition) by Joshua Bloch that should help you decide:

"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."

Hope that helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!