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?
OutOfMemoryError is a runtime error in Java which occurs when the Java Virtual Machine (JVM) is unable to allocate an object due to insufficient space in the Java heap. The Java Garbage Collector (GC) cannot free up the space required for a new object, which causes a java. lang. OutOfMemoryError .
OutOfMemoryError: PermGen space. As explained in the above paragraph this OutOfMemory error in java comes when the Permanent generation of heap is filled up. To fix this OutOfMemoryError in Java, you need to increase the heap size of the Perm space by using the JVM option "-XX: MaxPermSize".
When data structures or data sets that reside in memory become so large that the common language runtime is unable to allocate enough contiguous memory for them, an OutOfMemoryException exception results.
Increase Xmx in small increments (eg 512mb at a time), until you no longer experience the OutOfMemory error. This is because increasing the heap beyond the capabilities of your server to adequately Garbage Collect can cause other problems (eg performance/freezing)
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.
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.
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