javagarbage-collectionjvmjvm-hotspotg1gc

G1 does not allow to allocate large object while Parallel does


openjdk 11.0.14.1 2022-02-08

Consider the following simple Java program.

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

Here int is 4 byte in size so allocating int[Integer.MAX_VALUE / 2] requires 4G of free heap size. Now let's run the program with different options.

I. -XX:+UseParallelGC -Xmx5g

Result: Crash with OutOfMemoryError.

Even in spite of the fact that heap size is large enough. It's clear since the -XX:NewSize is 1310 MB by default and the Old generation is not large enough.

II. -XX:+UseParallelGC -Xmx5g -XX:MaxNewSize=128m -XX:NewSize=128m

Result: Completed normally

The application runs fine since the Old generation is large enough to hold the array allocation.

Now let's change the collector from Parallel to G1

III. -XX:+UseG1GC -Xmx5g -XX:MaxNewSize=128m -XX:NewSize=128m

Result: Crash with OutOfMemoryError.

And this is what I have no idea about. I thought that adjusting -XX:G1HeapWastePercent would help, but it didn't.

Why can't G1 hold the allocation of the array and what options to adjust in order to fix it?


Solution

  • This is a JVM bug JDK-8279241 "G1 Full GC does not always slide memory to bottom addresses". It should be resolved in JDK 19.

    The workaround is to disable Class Data Sharing. The test does not fail with -Xshare:off