OpsCanary
kubernetesschedulingPractitioner

Optimizing JVM Performance in AWS Kubernetes: Memory, CPU, and Classpath Best Practices

5 min read AWS Containers BlogJul 20, 2026Reviewed for accuracy
Share
PractitionerHands-on experience recommended

Java applications running in containers on AWS face unique challenges. The JVM needs to be aware of the container's resource limits to function efficiently. Misconfigurations can lead to performance degradation and unpredictable behavior, especially regarding memory and classpath management.

Modern JVMs (Java 10 and above) are designed to be container-aware. They read cgroup limits instead of relying on the host's memory settings. To ensure this feature is active, use the -XX:+UseContainerSupport flag, which is enabled by default. This allows the JVM to adapt its memory usage based on the actual resources allocated to the container. However, remember that low-level operations, like directory listings, still depend on the host kernel's behavior. Classpath management is another critical area. The order in which classes are loaded can lead to nondeterministic behavior if wildcard classpaths are used. Instead, explicitly define your classpath to ensure predictable loading.

In production, you should be aware of the implications of using wildcard classpaths. For example, instead of setting ENV CLASSPATH="/app/lib/*", define the classpath explicitly with the full paths of the JAR files. This approach avoids potential issues with class loading order. Additionally, ensure you are using a compatible JVM version; cgroups v2 support was introduced in JDK 15 and backported to earlier versions, so check your runtime environment.

By following these best practices, you can significantly improve the performance and reliability of your Java applications running in AWS Kubernetes.

Key takeaways

  • Enable container support with the -XX:+UseContainerSupport flag to optimize memory usage.
  • Define classpaths explicitly to avoid nondeterministic behavior in class loading.
  • Ensure your JVM version supports cgroups v2 for better resource management.

Why it matters

Proper JVM configuration can lead to significant performance improvements and stability for Java applications in production. Mismanagement can cause resource contention and application failures.

Code examples

Dockerfile
FROM amazoncorretto:17-al2023
Shell
# Avoid this: order is nondeterministic
ENV CLASSPATH="/app/lib/*"

# Use this: order is explicit and deterministic
ENV CLASSPATH="/app/lib/framework-core-2.1.0.jar:/app/lib/framework-utils-2.1.0.jar:/app/lib/logging-1.4.jar"
Maven Shade Plugin
1<plugin>
2    <groupId>org.apache.maven.plugins</groupId>
3    <artifactId>maven-shade-plugin</artifactId>
4    <version>3.6.0</version>
5    <executions>
6        <execution>
7            <phase>package</phase>
8            <goals>
9                <goal>shade</goal>
10            </goals>
11        </execution>
12    </executions>
13</plugin>

When NOT to use this

The official docs don't call out specific anti-patterns here. Use your judgment based on your scale and requirements.

Want the complete reference?

Read official docs

Test what you just learned

Quiz questions written from this article

Take the quiz →
Better StackSponsor

Unified observability — logs, uptime monitoring, and on-call in one place. Used by 50,000+ engineering teams to ship faster and sleep better.

Try Better Stack free →

Get the daily digest

One email. 5 articles. Every morning.

No spam. Unsubscribe anytime.