Search code examples
javajvmgarbage-collection

InitialRAMPercentage doesn't set initial heap size


We are running our Java application with OpenJDK 17.0.7 in a Docker container with these arguments (these are only relevant to my question):
-XX:InitialRAMPercentage=75.0 -XX:MaxRAMPercentage=75.0 -XX:MaxMetaspaceSize=1G -XX:+UseG1GC

Here is a picture from JDK Mission Control showing how the application starts:

Run an application with InitialRAMPercentage

You can see that Committed size was not the same all the time. It started at 3GiB and then it grew up to ~6GiB.

Then I changed VM Arguments to use Xms/Xmx instead of RAMPercentage:
-Xms6G -Xmx6G -XX:MaxMetaspaceSize=1G -XX:+UseG1GC

And now I see the picture I expected to see - Committed size is equals to 6GiB from the startup: Run an application with Xms/XMx

Is it an expected behavior of InitialRAMPercentage? Shouldn't it work the same way as Xms? Am I missing something?


Solution

  • A common misconception is that the initial heap size is the minimum heap size. They are actually different and can be configured separately: -XX:InitialHeapSize vs. -XX:MinHeapSize.

    In JDK 17, -Xms is a shortcut to set both InitialHeapSize and MinHeapSize to the same value. In contrast, -XX:InitialRAMPercentage affects InitialHeapSize only, and therefore heap may shrink below the initial size.

    If you want to prevent heap from resizing at runtime, disable heap shrinking with -XX:MaxHeapFreeRatio=100, or disable adaptive size policy altogether: -XX:-UseAdaptiveSizePolicy.

    Note: -XX:MinRAMPercentage does not help. Its name is confusing: the argument configures MaxHeapSize, not MinHeapSize - see JDK-8278492