Lets assume that we are talking about a 32bit OpenJDK-based JVM.
- Each Integer object has 1
int
field - occupying 4 bytes.
- Each Integer object has 2 header words - occupying 8 bytes.
- The granularity of allocation is (I believe) 2 words - 4 bytes of padding.
- The Integer[] has 1 reference for each array element / position - 4 bytes.
So the total is 20 bytes per array element. 20 x 30 x 1,000,000 = 600,000,000 Mbytes. Now add the fact that the generational collector will allocate at least 3 object spaces of various sizes, and that could easily add up to 900+ Mbytes.
how could i fix it ?
- Use
int[]
instead of Integer
.
- If the
Integer
values mostly represent numbers in the range -128 to + 127, allocate them with Integer.valueOf(int)
. The JLS guarantees that Integer
objects created that way will be shared. (Note that when an Integer
is created by auto-boxing, then JLS stipulates that valueOf
is used. So, in fact, this "fix" has already been applied in your example.)
- If your
Integer
values mostly come from a larger but still small domain, consider implementing your own cache for sharing Integer
objects.
My question was about Integer as an example, in my program i use my own object that only holds an array of bytes (max size of 4). when i create it, it takes a lot more then 4 bytes on the memory.
Yes, it will do.
Let's assume your class is defined like this:
public class MyInt {
private byte[] bytes = new byte[4];
}
Each MyInt
will occupy:
MyInt
header words - 8 bytes
MyInt.bytes
field - 4 byte
- Padding - 4 bytes
- Header words for the byte array - 12 bytes
- Array content - 4 bytes
Now add the space taken by the MyInt
reference:
- Reference to each
MyInt
- 4 bytes
Grand total - 36 bytes per MyInt
element of a MyInt[]
.
Compare that with 20 bytes per Integer
element of an Integer[]
or 4 bytes per int
element of an int[]
.
How to fix that case?
Well an array of 4 bytes contains 32 bits of data. That can be encoded as int
. So the fix is the same as before. Use an int[]
instead of a MyInt[]
, or (possibly) adapt one of the other ideas discussed above.
Alternatively, make the heap larger, or use a database or something like that so that the data doesn't need to be held in RAM.