Reputation: 653
How come if I execute the class below via: java -Xmx12m OOM
, it fails with the java.lang.OutOfMemoryError Java heap space
message. But if it works with java -Xmx13m OOM
.
class OOM {
static final int SIZE=2*1024*1024;
public static void main(String[] a) {
int[] i = new int[SIZE];
}
}
I thought int
is 4 bytes so 2*1024*1024*4=8,388,608bytes. It's still lower than 12, right? So how come -Xmx12m
fails but -Xmx13m
works?
Upvotes: 5
Views: 154
Reputation: 662
I agree with Stephan C.
I would like to provide some more info from this blog by Alexey Zhebel
Below diagram explains java memory architecture in detail.
Heap memory (-Xmx) = Youn gen (Eden space) + Survivor Space + Olde gen(Tenured space)
It seems that your total heap memory is crossing 12m but not exceeding 13m.
Upvotes: 2
Reputation: 718798
An -Xmx
option sets the total (maximum) heap size. However, a Java heap typically consists of 2 (or more) spaces1, and a Java object has to fit into a single space.
When you are setting the heap to 12mb, neither of the spaces is large enough2 to hold a single object of ~8mb. When you increase the total heap size to 13mb, one of the spaces is big enough.
1 - The "new" or "eden" space is where new objects are normally allocated. The "old" or "tenured" space is where objects end up after they have survived a certain number of GC cycles. However, really large objects (like yours) may be allocated directly into the "old" space. (Note: this is a simplification ...)
2 - It is possible to tweak the relative size the new space, but that has other consequences. For instance, if you reduce the size of the new space too much, you are likely to increase the percentage of "full" GCs ... which affects both throughput and GC pauses.
Upvotes: 4