Usage of Java flags InitialRAMPercentage and MaxRAMPercentage

Solution Verified - Updated

Environment

  • OpenJDK 11
  • OpenJDK 8 (backported after 1.8.191+)

Issue

  • How to use InitialRAMPercentage and Min|MaxRAMPercentage?
  • Are these JVM parameters applicable only for container environment or can we use in local machines: InitialRAMPercentage Min|MaxRAMPercentage?

Resolution

The JVM options InitialRAMPercentage and MaxRAMPercentage were introduced on JDK 10 and, therefore it can be used on OpenJDK 11, which is the version that Red Hat supports. However, those features were backported to OpenJDK 1.8.181, as described in the solution Should -XX:+UseContainerSupport flag be used in OpenJDK images and the Percentage flags replace the deprecated Fraction flags.

Although the usage of those three flags is in the context of containers (and therefore, combined with the UseContainerSupport flag that is enabled by default), they could be used outside a container, yes.

Usage example:

 JAVA_OPTS="-XX:+UseContainerSupport -XX:InitialRAMPercentage=70 -XX:MaxRAMPercentage=80 -Djava.net.preferIPv4Stack=true"

The Content from bugs.java.com is not included.deprecated Fraction flags had less control over the heap usage on the memory MaxRAMFraction, Min|MaxRAMFraction:

MaxHeapSize = MaxRAM * 1 / MaxRAMFraction

Explanation

FlagPurpose
MaxRAMPercentageSets the Max Heap size as a percentage of the container
InitialRAMPercentageSets the Initial Heap size as a percentage of the Max RAM

How the JVM calculates the heap and default values

As explained on the solution Should -XX:+UseContainerSupport flag be used in OpenJDK images?, the flag UseContainerSupport is enabled by default and enables the JVM to be aware that it is running in a Docker container and will extract container-specific configuration information: the number of CPUs and total memory that have been allocated to the container. So one does not need to set JAVA_MAX_INITIAL_MEM manually and the JVM will know the max memory from the pod itself.

Default values vs container default

The JVM default values for heap is 25% (1/4th of the value) as in Openjdk running on bare metal/VM
However, in a container given cgroups detection (v1 and v2 - for JDK 8/11/17), Xmx was set as 50% of the max memory resource limits (not requests) with an old version of the container scripts. This means that running a container without any memory limits, then the process in that container will get 50% of the host (by default) so the native get 50%. In updated container scripts in ubi8/ubi9 - RHEL 9 and RHEL 8 images, MaxRAMPercentage is being set to 80% by default. That means the max heap, based on the set container limit, will default to 80%. The remaining 20% are left for the native memory needs of the JVM/app.

EnvironmentValue
bare metal/ VMdefault is 1/4th - 25%
container (cgroups v1 and v2)ubi8: 80%, ubi9: 80% (both set via -XX:MaxRAMPercentage)*

*Note: Prior to JDK17, MaxRAMPercentage is based on MaxRAM, not system memory. The default max value for MaxRAM is 128g. For example, this results in a 64g max heap, not 100g, in a container with a 200g memory limit: -XX:MaxRAMPercentage=50. A workaround for using MaxRAMPercentage in environments with >128g available memory is to explicitly set MaxRAM to a higher value. For example, this would result in a 100g max heap in a container with a 200g memory limit: -XX:MaxRAMPercentage=50 -XX:MaxRAM=200g). See Content from bugs.openjdk.org is not included.JDK-8222252.

Xmx takes precedence

Xmx flag takes precedence over cgroups limits, but should be avoided to use given it is not a dynamic value.
Also setting Xmx takes precedence over the default Xmx calculate (see above).

Root Cause

Being container aware (default via UseContainerSupport) makes the usage of MaxRAMPercentage and MaxRAMFraction very useful, given that the JVM will automatically calculate the heap size (and non heap) from the total RAM. However, MaxRAMPercentage are more practical than MaxRAMFraction for most of the cases, hence the deprecation.

-XX:+UseContainerSupport flag is used by default and doesn't need to be set.

Category
Tags

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.