Short answer
A container memory limit is enforced by the kernel cgroup; if the JVM's heap plus non-heap (metaspace, thread stacks, direct buffers, code cache) exceeds it, the kernel OOM-kills the process and Kubernetes restarts it — often misdiagnosed as a memory leak.
Explanation
Modern JVMs honor cgroup limits via UseContainerSupport and you set MaxRAMPercentage (e.g. 75%) so heap leaves headroom for non-heap, rather than hardcoding -Xmx and forgetting off-heap usage. Set the container limit and the JVM sizing together, and remember a memory limit overage is a kill while a CPU limit overage is mere throttling.
Common mistakes
- Hard-coding -Xmx larger than the container limit.
- Not using -XX:MaxRAMPercentage.