aws AWS Containers Blog ·

AWS Java Container Best Practices for JVM Memory, CPU, and Classpath

bloginfraawsengineer
announcement

This post details best practices for managing JVM memory, CPU, and classpath within Java containers on AWS ECS and EKS. It addresses nondeterministic classpath resolution and resource allocation mismatches that can cause production failures, even without code changes. The article explains how JVMs interact with container runtimes and host kernels, offering configuration strategies to prevent these issues, which are common across AWS Fargate and EC2.

  • Understanding Container Kernel Sharing
  • Nondeterministic Classpath Resolution Issues
  • Best Practices for Classpath Management
  • JVM Resource Detection Mismatches
  • Impact of Host Updates on JVM Behavior
Notes (5)
  • Understanding Container Kernel Sharing

    Containers share the host kernel, meaning syscalls from within a container are handled by the host's kernel, regardless of the user space distribution. This shared kernel behavior can influence low-level operations like directory listings that the JVM relies on, even with container-aware JVMs.

  • Nondeterministic Classpath Resolution Issues

    Classpath issues arise from nondeterministic ordering in wildcard classpath expansion (e.g., lib/*) and when multiple JARs with different class versions exist. This can lead to ClassNotFoundException or NoClassDefFoundError, often surfacing after host updates or redeployments due to underlying filesystem behavior.

  • Best Practices for Classpath Management

    To mitigate classpath issues, the recommended approach is to bundle dependencies into fat JARs. If not feasible, alternatives include using frameworks with deterministic packaging (Spring Boot nested JARs, Quarkus, Micronaut), detecting version conflicts at build time, relocating conflicting dependencies, and preferring explicit classpath ordering over wildcards.

  • JVM Resource Detection Mismatches

    Resource allocation mismatches occur when the JVM's default settings for memory and CPU don't align with container limits. This can lead to OutOfMemory (OOM) kills if the JVM allocates too much heap or oversubscribes resources, especially when older JVMs read host memory or when non-heap memory pushes usage over the limit.

  • Impact of Host Updates on JVM Behavior

    Routine host operating system updates, including kernel patches on Fargate or AMI updates on EC2, can alter filesystem behavior. These changes can indirectly affect how the JVM resolves classpaths or detects resources, leading to unexpected application failures without any changes to the container image or application code.

Read the original announcement →

https://aws.amazon.com/blogs/containers/jvm-memory-cpu-and-classpath-best-practices-for-java-containers-on-aws/

Related releases