Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does OutOfMemoryError occur for -Xmx12m but not -Xmx13m?

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?

like image 230
user2345093 Avatar asked May 15 '16 03:05

user2345093


People also ask

What causes OutOfMemoryError?

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 .

How can we avoid OutOfMemory errors?

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".

What is out of memory exception?

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.

How do I fix out of memory errors by increasing available memory?

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)


2 Answers

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.

like image 123
Stephen C Avatar answered Nov 15 '22 00:11

Stephen C


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.

enter image description here

like image 41
Aditya W Avatar answered Nov 14 '22 23:11

Aditya W