32 bits. It's one of the Java language features that the size of the integer does not vary with the underlying computer. See the relevant section of the spec.
Answer from Thomas Jones-Low on Stack OverflowOn a 64-bit machine is the size of an int in Java 32 bits or 64 bits? - Stack Overflow
How do I create a user defined array size? - Post.Byes
size of int in java
Why the size of Java <int> data type has always been fixed versus to, for instance, the <int> size in C or C++?
Videos
32 bits. It's one of the Java language features that the size of the integer does not vary with the underlying computer. See the relevant section of the spec.
The size of primitive data is part of the virtual machine specification, and doesn't change. What will change is the size of object references, from 32 bits to 64. So, the same program will require more memory on a 64 bit JVM. The impact this has depends on your application, but can be significant.
How many bytes does an int[] vs. Integer[] be in memory? Like including the overhead and extra data required, not just the data itself? I know it has an additional length which is an int (8 bytes).
A primitive int obviously takes 4 byte.
An Integer object has an overhead of about 24 byte (this is implementation specific) plus 4 byte for the data, so about 28 byte.
An array is an object which also has an overhead of 24 bytes plus 4 bytes for the length plus data.
An int[] array thus uses 28 bytes plus 4 bytes for each int.
An Integer[] array uses 28 bytes plus 4-8 bytes to reference each Integer object plus 28 byte for each unique Integer object. In the worst case with uncached and unique Integer objects, this equals to 28 bytes array overhead plus 36 bytes for each value.
There are two things you have to take into account here:
-
Overhead for the data itself (int vs. Integer)
-
Overhead for the object reference
So, let's start :)
-
Integer vs. int.
Primitive int is just a 4 bytes value (not 8 bytes as you've written). Integer is an object, which consists of a primitive int value (4 bytes) and object header. Object header can be 8, 12, or 16 bytes depending on the bitness of your JVM and UseCompressedOops flag. Here is Stackoverflow answer that describes the structure of the object header: https://stackoverflow.com/questions/26357186/what-is-in-java-object-header
UseCompressedOops is a flag that makes JVM optimize most of the references on 64-bit JVM and make them take 32 bits instead of 64 bits. If set, it should also make object header take 12 bytes instead of 16 bytes. (To be honest, I didn't measure this).
Given that, the overhead for a bunch of integers will be
number_of_elements * object_header_overhead
, where object_header_overhead =
-
8 bytes (on 32 bit JVM)
-
12 bytes (on 64 bit JVM with UseCompressedOops = true)
-
16 bytes (on 64 bit without compressed oops)
But that's not the end of the story.
2. Size of object reference
int is a primitive, in another words it's just 4 bytes of data, and that's it. Integer is an object, which means it should be referenced from some another place in your program. If it is not referenced from anywhere, it's lost (and soon will be eaten by the GC).
Now, if you have an array of ints, then each element of it is a 4 byte int value. If you have an array of Integers, each element of it will be not Integer, but a reference to Integer object.
The size of an object reference is also can be different on different JVMs:
- 32 bits on 32 bit JVM
- 64 bits on 64 bit JVM
- 32 bits on 64 bit JVM with UseCompressedOops
Now you can calculate total overhead for your specific case. Here are few examples:
-
Say, you run the following code on 32 bit JVM:
i1 = new Integer[100];
i2 = new int[100];
These are just empty arrays. The memory taken by them will be exactly the same, because each element of each array will take 4 bytes (0 int is 4 bytes, and null is 32 bits on 32 bit JVM).
2. Now, say you have 64 bit JVM without compressed oops.
i1 = new Integer[100];
i2 = new int[100];
for (int i = 0; i < 100; i++) {
i1[i] = i; // implicit boxing: new Integer(i);
i2[i] = i;
}
Now the memory taken by a single element of Integer array will consist of:
-
4 bytes int value
-
16 bytes - object header
-
8 bytes object reference,
while an element of int array will only take 4 bytes. In total you have (16 + 8) * 100 = 240 bytes.
3. Of course, you can have more complicated situations, for instance (let's say, we have 64 bit JVM again):
i1 = new Integer[100];
i2 = new int[100];
int primInt = 42;
Integer wrappedInt = new Integer(42);
for (int i = 0; i < 100; i++) {
i1[i] = wrappedInt;
i2[i] = primInt;
}
As you can see, now every element of Integer array references a single Integer object. So, the total memory overhead will consist of:
-
100 * 4 bytes (4 bytes for primitive int vs. 8 bytes for object reference on 64 bit JVM)
-
20 bytes (size of the single Integer object, consisting of 16 bytes for the header and 4 bytes for the int value).
And couple more things to add:
-
I don't guarantee that the information about the size of object header is 100% correct. This is what I remember about it, so please verify it yourself if you need to.
-
Things can get even more complicated, because Java tends to cache Integers and reuse them. So actual memory of your programs can be less than expected.