OwlR
OwlR

Reputation: 451

java.lang.OutOfMemoryError: Java heap space exception

I got "java.lang.OutOfMemoryError: Java heap space" exception while running following code snippet. I have set JVM heap size 8192M with command set JVM_ARGS="-Xms8192m -Xmx8192m".

    List<Integer> largeList = new ArrayList<>();

    Random rand = new Random();

    for(int i=0;i<Integer.MAX_VALUE/2;i++)
    {
        largeList.add(rand.nextInt(Integer.MAX_VALUE));
    }

I think JVM heapsize, I set, is big enough to hold array.

Upvotes: 3

Views: 1415

Answers (3)

Joachim Sauer
Joachim Sauer

Reputation: 308001

A List can only hold objects.

An Integer object needs at least 4 byte for the actual value and some amount of bytes for various object-related overhead (varies by JVM, but is usually around 16-30 bytes per object).

Integer.MAX_VALUE / 2 is about a billion. So for the data alone (without object overhead) you'd need 4 billion bytes to store the list. That's 4GB. So even if the object overhead was only 4 bytes (very hard to do, and probably not very efficient at runtime), that would already use up all 8GB of your heap (and leave nothing for all of the classes needed to run your code). And that doesn't even include the memory held for the ArrayList which needs to hold that many references (which are either 8 or 4 bytes, depending on what JVM and which settings you use).

So no, you've not assigned it nearly enough memory.

If you actually need that many int values, consider using a int[] which is significantly more memory efficient than that, effectively taking 4 bytes per int with a small fixed-sized overhead.

Upvotes: 8

assylias
assylias

Reputation: 328568

When the ArrayList is full, its size is increased by 50% - so the size of your list may be as high as 0.75 * MAX_VALUE = 0.75 * 2^31 = 1.6 billion.

An Integer takes 16 bytes in memory, and each Integer reference takes 4 or 8 bytes in the list. Lets assume 4 here. So your list could take up to 1 billion * 16 + 0.6 billion * 4 (for null entries) = 30 GB in memory.

Upvotes: 4

Robert Hume
Robert Hume

Reputation: 1171

The size of a int is 4 bytes, so in theory you'll have more than 4 GB of Integers in your heap due to the wrapper's overhead; another point is that ArrayList changes its size by using Arrays.copyOf(), so more memory is needed to resize the list itself to ensure its capacity is enough while filling.

Upvotes: 0

Related Questions