How large, in bytes, is a boxed primitive like java.lang.Integer
or java.lang.Character
in Java?
An int
is 4 bytes, a typical pointer is also 4 byte (if not compressed by the JVM). Is the cost for an Integer (without caching) thus 4 bytes + 4 bytes = 8 bytes
? Are there any more hidden fields within the box-object or additional overhead incurred regarding objects (i.e. is there a general cost for objects that I'm not aware of?).
I'm not interested in caching issues. I know that Integers within a certain range are cached by the JVM.
One could rephrase the question: What is the maximum factor to be multiplied on the amount of memory used for boxed values versus primitive values?
EDIT: I do understand that multiple implementations of the JVM exist. What is the typical cost in a typical 32-bit HotSpot Implementation?
In Java, when primitive values are boxed into a wrapper object, certain values (any boolean, any byte, any char from 0 to 127, and any short or int between -128 and 127) are interned, and any two boxing conversions of one of these values are guaranteed to result in the same object.
Primitives simply represent a value, like the number seven or the boolean value of false. They have no methods and no complementary properties. Also, you can't do much with them other than inspect their value or perhaps change the value that they hold. But they are not, by any means, objects.
Boxed means that they took a regular value type and created an object around it. Sort of like putting it in a box. This is generally to be avoided, because of the overhead of constructing the object.
Instead of create variables using new, Java can use primitive types to create automatic variables that are not references. The variables hold the value, and it's place on the stack so its much more efficient. Java determines the size of each primitive type.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With