Quoting Troubleshooting Guide for Java SE 6 with HotSpot VM
3.1.3 Detail Message: Requested array size exceeds VM limit
(inline bold is mine):
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 larger than the heap size. For example, if an application attempts to allocate an array of 512MB but the maximum heap size is 256MB then OutOfMemoryError
will be thrown with the reason Requested array size exceeds VM limit
. In most cases the problem is either a configuration issue (heap size too small), or a bug that results in an application attempting to create a huge array, for example, when the number of elements in the array are computed using an algorithm that computes an incorrect size.
UPDATE: encouraged by the @Pacerier I did some quick testing. I wrote a sample program:
public class VmLimitTest {
public static final int SIZE = 2;
public static void main(String[] args) throws InterruptedException {
while(true) {
byte[] a = new byte[SIZE * 1024 * 1024];
TimeUnit.MILLISECONDS.sleep(10);
}
}
}
And run it with the following JVM options:
-Xms192m -Xmx192m -XX:NewRatio=2 -XX:SurvivorRatio=6 -XX:+PrintGCDetails
This is what they mean:
- The whole heap is 192 MiB (
-Xms192m -Xmx192m
)
- The young generation (eden + survivor) space is 64 MiB, old generation is 128 MiB (
-XX:NewRatio=2
)
- Each survivor space (out of two) is 8 MiB, so 48 MiB is left for eden (1:6 ratio,
-XX:SurvivorRatio=6
)
While testing I discovered the following:
- If the newly created array can fit into eden (less than 48 MiB), the program runs fine
- Surprisingly, when the array size exceeds eden size, but can fit into eden and one survivor space (between 48 and 56 MiB), JVM can allocate a single object on both eden and survivor (overlapping two areas). Neat!
- Once the array size exceeds eden + single survivor (above 56 MiB) the newly created object is placed directly in old generation, bypassing eden and survivor spaces. This also means that suddenly full GC is performed all the time - very bad!
- I can easily allocate 127 MiB of data but trying to allocate 129 MiB will throw
OutOfMemoryError: Java heap space
This is the bottom line - you cannot create an object with size larger than old generation. Trying to do so will result in OutOfMemoryError: Java heap space
error. So when can we expect dreadful Requested array size exceeds VM limit
?
I tried running the same program with much larger objects. Hitting the array length limit I switched to long[]
and could easily go up to 7 GiB. With 128 MiB of max heap declared the JVM was still throwing OutOfMemoryError: Java heap space
(!) I managed to trigger OutOfMemoryError: Requested array size exceeds VM limit
error trying to allocate 8 GiB in a single object. I tested this on a 32-bit Linux computer with 3 GiB of physical memory and 1 GiB of swap.
That being said you should probably never hit this error. The documentation seems inaccurate/outdated, but it is true in one conclusion: this is probably a bug since creating such huge arrays is very uncommon.