OOM: Requested array size exceeds VM limit

System Context

  • The array size in Java is internally indexed using an int, so:

    • The maximum theoretical indexable size is Integer.MAX_VALUE (2,147,483,647).

    • But in practice, the actual allocatable size is lower due to:

      • JVM implementation overhead

      • Object header memory

      • Alignment and padding

      • 32-bit vs 64-bit architecture

  • The error message comes from the JVM before trying to allocate the memory — as a preventive measure, not after a failed memory allocation.

This error occurs when a Java application attempts to allocate an array that exceeds the size limit imposed by the JVM. Even if the system has enough heap memory available, the JVM may still refuse such an allocation due to array size limitations defined by the Java Virtual Machine Specification.

Observed Problem

We might see the following error at runtime:

Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit

This is not the typical OutOfMemoryError due to heap exhaustion. Instead, it indicates that the array we are trying to create exceeds what the JVM allowseven if there is enough heap memory available.

Understanding the Error

What Causes This?

Java does not allow creation of an array with a size that:

  1. Exceeds the hard-coded JVM safety limit (~Integer.MAX_VALUE - 8 depending on the JVM).

  2. Would result in an actual memory allocation that’s too large, even if the size value is technically within bounds.

Example:

public class Main {
    public static void main(String[] args) {
        int[] a = new int[Integer.MAX_VALUE]; // 2_147_483_647
    }
}

Even though this is technically valid according to the Java language (int index range), it will likely throw:

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

Why?

  • Each int takes 4 bytes.

  • So this array would require: Integer.MAX_VALUE * 4 = ~8 GB (plus some JVM internal memory for array headers).

  • On a typical 64-bit JVM, this might work only if we increase the heap size significantly (e.g., -Xmx10g), but most JVMs still prevent allocation near this upper limit.

Common Scenarios

  • Declaring very large arrays directly (new byte[Integer.MAX_VALUE])

  • Creating large multidimensional arrays (e.g., new int[100000][100000])

  • Using memory-intensive structures with large data volume

  • Poor memory planning in data-processing loops

  • Bulk data ingestion from files or streams without paging

How JVM Restricts Array Sizes

  • The limit is typically around Integer.MAX_VALUE - 8

  • JVM adds overhead for metadata (object header + array header)

  • The exact limit can vary based on JVM implementation

Avoiding the Error

Validate Input

Ensure any user-defined or dynamic size is within safe bounds:

int size = calculateSize();
if (size < 0 || size > MAX_SAFE_ARRAY_SIZE) {
    throw new IllegalArgumentException("Invalid array size");
}

Use Collections

Use ArrayList, HashMap, or other data structures that handle resizing internally, rather than manually allocating huge arrays.

Use Chunking

Break data into chunks or batches instead of loading all at once:

List<int[]> batches = new ArrayList<>();
for (int i = 0; i < largeSize; i += CHUNK_SIZE) {
    batches.add(new int[Math.min(CHUNK_SIZE, largeSize - i)]);
}

Adjust JVM Heap Parameters (if applicable)

If we're confident about the memory size, and the system has enough RAM:

java -Xmx10g -XX:-UseCompressedOops -cp . Main

But even with -Xmx10g, array allocations may still be refused if they’re beyond the safe limit.

Last updated

Was this helpful?