Java Heap settings Best Practice

Article ID:204859670
3 minute readKnowledge base

Issue

  • Best Practice For Java Memory Heap settings

Explanation

In a traditional platform, where Jenkins runs on the system directly, the java arguments Xmx and Xms can be used to set respectively the maximum and the initial JVM memory heap sizes.

In a modern platform or when running Jenkins in a container, those settings are deprecated. Since JDK 8u191 XX:+UseContainerSupport is activated by default, the JVM is "container-aware" and can determine its heap size based on the container boundaries. It also introduces -XX:MaxRAMPercentage / -XX:InitialRAMPercentage which takes a value between 0 and 100 (Note: values should be double type see docker-library/openjdk/issues/350). This allows fine-grained control of the amount of RAM the JVM is allowed to allocate.

Resolution

Traditional Platform

Use -Xmx and -Xms

Recommended Heap Specifications can be found in CloudBees JVM Guide.

Modern Platform

Ensure container memory limits / requests are equal and use -XX:InitialRAMPercentage / -XX:MaxRAMPercentage

For Jenkins instances, it is recommended to use a Guaranteed QoS (same request and limits) to avoid impact with other containers and unexpected evictions and restarts caused by node memory pressures.

... resources: limits: memory: 6Gi requests: memory: 6Gi ...

Defining just the limits assumes the same requests value.

... resources: limits: memory: 6Gi ...

Add -XX:InitialRAMPercentage=50.0 -XX:MaxRAMPercentage=50.0 Java arguments as per How to add Java arguments to Jenkins.

Notes

a. Do not enable Enable heap ratio because it calculates the JVM Heap size from the Jenkins Controller Memory in MB and injects -Xmx and -Xms to the controllers JVM (which is not recommended).

b. Do not set -Xmx / -Xms. Those options set the JVM Heap size directly and it is best to let the JVM infer these based on current limits. Use -XX:MaxRAMPercentage / -XX:InitialRAMPercentage instead. If -Xmx is passed, the JVM will ignore -XX:MaxRAMPercentage (respectively, if -Xms is passed, the JVM will ignore -XX:InitialRAMPercentage).

c. Do not use a ratio JVM heap / Container Memory limit higher than 0.5. It is known to be unstable and may cause unexpected controller restarts due to JVM off heap usage. Note that the JVM default to use a ratio of 0.25.

d. Do not set -XX:MinRAMPercentage. It is used to compute Java heap size only if your overall available memory’s size in the physical server (or in the container) is less than 250MB (approximately). A Host with 250 MB of memory would not been able to support the minimal requirement of Heap Size for CloudBees CI on Production Enviroments: 4GB (See CloudBees Jenkins JVM troubleshooting - Heap Size).

e. Do not set -XX:MaxRAMFraction. It is deprecated in favor of MaxRAMPercentage see JDK-8186315 and After upgrading CloudBees CI on modern platform, the Operation Center - Controller is getting restarted often.

For a more detailed explanation on the meaning of InitialRAMPercentage, MinRAMPercentage, MaxRAMPercentage, refer to Differences between InitialRAMPercentage, MinRAMPercentage, MaxRAMPercentage.

Memory Estimation

Use your favorite APM tool to monitor the Memory Heap Consumption by your instance. The right heap value should be a value between 80-90% of total heap consumption when the instance is at the maximum workload. Increased heap memory will produce long Garbage Collection pauses, which can be observed via slowness in the UI and sometimes even side effects like agent disconnections.

Horizontal Scaling

If your instance is not able to support its current workload (due to number of jobs and dynamic configurations) you should consider scaling horizontally your infrastructure by adding more controllers to divide the workload more efficiently.

References: