Java in a containermedium3-5 years

A Spring Boot container is given a 1 GiB memory limit with no `-Xmx` or `-XX:MaxRAMPercentage` flag set, on a current JDK. It runs fine under light load, then gets killed under a traffic spike with no exception in the application log. What happened, and what's the fix?

A current JVM reads the container's cgroup memory limit and sizes its default heap as a fraction of it, so it isn't blindly guessing — but the kernel enforces the 1 GiB limit against the whole process, not just the heap: Metaspace, thread stacks, direct buffers, the native allocator's own overhead all count too. Under light load the heap and everything around it comfortably fits; under a spike, more threads spin up (more stacks), more classes may load (more Metaspace), and the total process footprint can cross 1 GiB even though the heap itself never exceeded whatever it was sized to. The kernel's cgroup enforcement kills the process outright — OOMKilled, exit code 137 — with nothing in the Java log, because there was no Java exception; the JVM was never given the chance to log anything, it was just gone. The fix is setting -XX:MaxRAMPercentage deliberately (75% is a common starting point for a service) rather than relying on the JVM's default (25%, sized for a laptop shared with other programs) or leaving explicit room for everything that isn't heap, and adding -XX:+ExitOnOutOfMemoryError so a genuine heap exhaustion at least produces a clean, loggable exit rather than a JVM stuck answering health checks with nothing else working.

The lesson behind it →
More on Java in a container