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

4

18

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?

Prosy answered 27/1, 2012 at 17:29 Comment(4)
From a certain perspective, this question is unanswerable because the overhead on a boxed primitive is not specified in any specification. It can and will vary from VM to VM and platform to platform. A hardware platform with tagged memory could even have zero overhead.Harakiri
duplicate of In Java, what is the best way to determine the size of an object?.Influx
I think it could also depend on the context you are using the boxed int and any optimizations the runtime compiler is making.Responsive
See also is-an-array-of-one-boolean-in-java-smaller-than-a-standalone-variableAnyplace
F
12

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

Firstnighter answered 27/1, 2012 at 17:55 Comment(3)
for the sake of completeness: if the object is synchronized upon, there will be a native struct holding the mutex.Helenehelenka
@Helenehelenka Right, completely ignored that. I think heavyweight locks are only created if we have a contended lock (assuming biased locking). If we don't, and don't use the hashcode of the object I think Hotspot stores the tid in the object header itself. So just calling synchronized(foo) may not necessarily allocate any memory.Firstnighter
yes. uncontended biased locks do not inflate the header if there is System.identityHashCode() request. The latter is used (unofficiallY) to prevent biased locking on a selected object. (i mean mostly contented -> sometimes i used Object lock =new Byte(1) to simplify serializationHelenehelenka
L
1

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.

Levelheaded answered 27/1, 2012 at 17:38 Comment(1)
I've got not the slightest idea how you come up with those numbers.. looking at my Hotspot source in oop.hpp also makes me none the wiser (I can only find the usual 2 pointers there)Firstnighter
K
1

One very small addition for these answers is that there is some deduplication happening for boxed primitives. For example, Integer::valueOf(int) uses java.lang.IntegerCache that uses Integer instances with values in range -128..127. So, you have above mentioned sizes for boxed objects, but not each of them would be a separate object.

Keele answered 13/9, 2019 at 16:37 Comment(0)
T
0

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 parameterized types (Chapter 5), because the language does not permit you to use primitives. 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.

Trisa answered 27/1, 2012 at 18:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.