Tags: Java, JVM, Resources
TABLE OF CONTENTS
- Resource limits considerations
- Troubleshooting Java parameters and resource usage
- References and additional reading
Resource limits considerations
Java applications on Kubernetes and in containers may require special tuning to make sure that memory and CPU usage and is based on the container cgroup limits rather than on physical machines settings.
As a rule of thumb, JVM uses 50%-100% more RAM than the max heap size, so normally it is safe to set container memory limit to the value 2X the max heap size (-Xmx parameter value).
This means that when configuring the application parameters, memory limits must be changed in a coordinated fashion in the pod resources section and in the JVM parameters.
Starting with version 1.8 JVM may be made aware of cgroups and use cgroup limits to get the amount of available resources - CPU and RAM.
This allows to avoid specifying memory limits in two places and specify the max heap size as a percentage of the container cgroup limit.
To achieve that
- In JDK 8u131 to 8u190 only specify -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=... -XX:MinRAMFraction=... JVM arguments instead of -Xmx and -Xms
- In JDK 8u191 and later specify -XX:MaxRAMPercentage and -XX:MinRAMPercentage JVM arguments instead of -Xmx and -Xms.
The following examples show invariant setting of JVM max heap size to a specific share of the container cgroups RAM limit:
# Container is not limited, MaxHeap is set to 25% (default) of total physical RAM docker run --rm \ openjdk:8-jdk java \ -XX:+PrintFlagsFinal -version | grep -i MaxHeap # Container is limited to 4G, MaxHeap is set to 25% (default) of the container limit docker run --rm -m 4g \ openjdk:8-jdk java \ -XX:+PrintFlagsFinal -version | grep -i MaxHeap # Container is limited to 4G, MaxHeap is set to 65% of the container limit docker run --rm -m 4g \ openjdk:8-jdk java \ -XX:MaxRAMPercentage=65.0 \ -XX:+PrintFlagsFinal -version | grep -i MaxHeap
Troubleshooting Java parameters and resource usage
Effective JVM parameters may be checked by running:
java -XX:+PrintFlagsFinal -version
References and additional reading
- https://hub.docker.com/_/openjdk
- https://blog.softwaremill.com/docker-support-in-new-java-8-finally-fd595df0ca54
- https://stackoverflow.com/questions/54292282/clarification-of-meaning-new-jvm-memory-parameters-initialrampercentage-and-minr/54297753#54297753
- https://blog.ycrash.io/2020/11/23/best-practices-java-memory-arguments-for-containers/