I was playing with OOM errors today and I found something I can't explain myself.
I try to allocate an array bigger than the heap, expecting a "Requested array size exceeds VM limit" error, but I get a "Java heap space" error instead.
According to the JDK 11 documentation "3 Troubleshoot Memory Leaks > Understand the OutOfMemoryError Exception" :
Exception in thread thread_name: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
Cause: The detail message "Requested array size exceeds VM limit" indicates that the application (or APIs used by that application) attempted to allocate an array that is largerthan the heap size. For example, if an application attempts to allocate an array of 512 MB, but the maximum heap size is 256 MB, then OutOfMemoryError will be thrown with the reason “Requested array size exceeds VM limit."
Code :
public class MemOverflow {
public static void main(final String[] args) {
System.out.println("Heap max size: " + (Runtime.getRuntime().maxMemory() / 1024 / 1024) + "MB");
long[] array = new long[100_000_000]; // ~800MB
System.out.println(array.length);
}
}
This code works as expected with a heap big enough to store my array :
$ javac MemOverflow.java && java -Xmx800m MemOverflow
Heap max size: 800MB
100000000
However, when I reduce my heap size I get the wrong OOM error :
$ javac MemOverflow.java && java -Xmx100m MemOverflow
Heap max size: 100MB
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at MemOverflow.main(MemOverflow.java:5)
# I'm expected the "Requested array size exceeds VM limit" error here
Am I missing something here ? I know I can generate the error I want using Integer.MAX_VALUE
as the array size, but I would like it to be thrown by adjusting the heap size.
Java version :
openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10-post-Ubuntu-0ubuntu120.04)
OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Ubuntu-0ubuntu120.04, mixed mode)
Edit: Based on @cdalxndr answer, I also tried with the Oracle latest JDK 15 but I get the same result.
java version "15" 2020-09-15
Java(TM) SE Runtime Environment (build 15+36-1562)
Java HotSpot(TM) 64-Bit Server VM (build 15+36-1562, mixed mode, sharing)
Edit 2: I reported it: JDK-8254804.
Edit 3: 2021-01-19 update
The documentation has been fixed. in the v16-ea (early access).
Exception in thread thread_name: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
Cause: The detail message "Requested array size exceeds VM limit" indicates that the application (or APIs used by that application) attempted to allocate an array with a size larger than the JVM implementation limit, irrespective of how much heap size is available.
Edit 4 : 2021-03-20 update
Requested array size exceeds VM limit
you should just check the OpenJDK sources instead of guessing... github.com/openjdk/jdk/… There is for example a unit test that callsObject[] oa = new Object[Integer.MAX_VALUE];
which causes this error. May be you don't get the error on primitive arrays? – Sinapismnew long[Integer.MAX_VALUE];
then I get the expected error. But If my heap is only 100MB then I should have this error when I try to allocate more than 100MB, even if it's not the max int value (well, this is what the documentation says). – Slipsheet