Your Spring Boot service in Kubernetes keeps restarting with exit code 137. How do you investigate and fix it?
BackendSenior
In shortExit 137 is a kill by the kernel's OOM killer when the container goes over its memory limit, not a Java OutOfMemoryError. Usually the heap is sized too close to the limit; leave headroom with MaxRAMPercentage around 75% and check non-heap memory with Native Memory Tracking.
Model answer
What 137 means: 128 + 9, the process got SIGKILL. In Kubernetes the pod status shows OOMKilled: total process memory crossed the container’s memory limit and the kernel killed it instantly, so there’s no Java stack trace.
Why it happens: the JVM uses more than its heap. Metaspace (100–200 MB for a Spring app), the code cache, about 1 MB per platform thread stack, direct buffers for Netty and HTTP clients, and GC structures all live outside -Xmx. A config like -Xmx2g in a 2 GiB container is guaranteed to get killed once the heap fills up.
How to investigate:
- Confirm
OOMKilledinkubectl describe podand look at the memory graph: a slow climb (leak or growing cache) or a spike (a large request, a burst of threads)? - Check the JVM flags actually in effect (
jcmd <pid> VM.flags) and the heap size the JVM picked. - Enable
-XX:NativeMemoryTracking=summaryand comparejcmd <pid> VM.native_memory summarywith the container’s memory usage to see which area grows. - If the heap itself grows, take a heap dump (
-XX:+HeapDumpOnOutOfMemoryError, orjcmd GC.heap_dump) and look for the leak.
Fix: size the heap as a percentage, -XX:MaxRAMPercentage=75, so a quarter of the limit is left for everything else; add -XX:+ExitOnOutOfMemoryError for clean restarts; cap thread pools and off-heap caches. Only raise the limit once you know what the memory is for.
What they're looking for
Knowing 137 means SIGKILL from the cgroup OOM killer, that JVM memory is heap plus metaspace, code cache, thread stacks and direct buffers, container-aware defaults (25% heap), percentage-based sizing, and a measured investigation instead of just raising the limit.
Common mistakes
- Searching the logs for an OutOfMemoryError that never gets written.
- Setting -Xmx equal to the container limit.
- Raising the memory limit without finding what grows.
- Forgetting thread stacks when a pool has hundreds of platform threads.
More backend questions
- What is the N+1 query problem, and how do you find and fix it?Mid-level
- What does Spring Boot's auto-configuration do, and how do you change what it set up?Mid-level
- How does a Spring backend authenticate requests from a mobile app, and how do you make sure users only see their own data?Mid-level
- A Java service's p99 latency spikes every few minutes. How do you find the cause?Senior