Debugging OOMKilled Spring Boot in Kubernetes
Fast recall
Quick revision
Core answer
OOMKilled (exit code 137) means the cgroup limit was breached — the kernel SIGKILLed the container. First confirm kill reason with kubectl describe pod. Then classify: heap exhaustion (leak or undersized -Xmx), metaspace overflow (classloader leak), or thread stack accumulation. Use jcmd VM.native_memory and jstat -gcutil for live diagnosis; -XX:+HeapDumpOnOutOfMemoryError + kubectl cp for forensic heap dumps. Fix with -XX:MaxRAMPercentage=75.0 (not -Xmx = limit) plus leak repair if confirmed.Production debugging skills for the most common JVM + container failure mode
Raising the memory limit without diagnosing root cause — fixes the symptom, hides a potential leak that will return at higher scale
Distinguish kernel OOMKill (exit 137) from JVM OutOfMemoryError, show `jcmd VM.native_memory` breakdown, separate heap/metaspace/thread leaks, explain how to copy a heap dump from a dying pod
Interview-ready guide
Interview answer
OOMKilled means the kernel killed the container because it exceeded its memory limit — the container runtime reported exit code 137, not a JVM OutOfMemoryError. Distinguishing these two is the starting point for diagnosis.
Immediate diagnosis
kubectl describe podunderLast StateshowsOOMKilledwithexitCode: 137— this is kernel cgroup kill, not Java heap exhaustion; the JVM had no warning and no heap dump was written automatically.kubectl get events --namespaceshows memory events and node pressure conditions around the kill.--sort-by='.lastTimestamp' - Compare
kubectl top pod(live RSS) againstresources.limits.memory— if RSS is consistently at or above limit, the limit is too low for the actual footprint.
Root-cause classification
- Heap too small for the workload: raise
-XX:MaxRAMPercentageor the container memory limit; add-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprofso the next event produces a dump. - Non-heap exhaustion: thread stacks (1 MB default), metaspace, direct buffers live outside heap limits; a service with 100 active threads consumes 100 MB of stack alone — check with
kubectl exec.-- jcmd 1 Thread.print | grep -c 'java.lang.Thread.State' - Memory leak: RSS grows continuously even at stable traffic; multiple heap dumps over time or JFR recording identifies the leaking object type in Eclipse MAT.
Heap dump extraction
- Running pod:
kubectl execthen-- jcmd 1 GC.heap_dump /tmp/heap.hprof kubectl cp— open in Eclipse MAT and use Leak Suspects.:/tmp/heap.hprof ./heap.hprof - After a kill: mount an
emptyDirvolume at/tmpand setHeapDumpPath=/tmp/so the dump persists briefly after container exit; copy it out before the next start overwrites.
The fix, not just the bandaid
-XX:MaxRAMPercentage=75.0with-XX:+UseContainerSupportkeeps heap at 75% of the cgroup automatically — no hardcoded-Xmxto forget; the remaining 25% covers non-heap.- If
jstat -gcutilshows Old Gen climbing after every full GC, the limit fix is a bandaid — you have a leak; do the heap dump and fix the retaining code before shipping a memory-limit bump.
Debugging OOMKilled Spring Boot in Kubernetes
Direct Answer
OOMKilled (exit code 137) means the cgroup limit was breached — the kernel SIGKILLed the container. First confirm kill reason with kubectl describe pod. Then classify: heap exhaustion (leak or undersized -Xmx), metaspace overflow (classloader leak), or thread stack accumulation. Use jcmd VM.native_memory and jstat -gcutil for live diagnosis; -XX:+HeapDumpOnOutOfMemoryError + kubectl cp for forensic heap dumps. Fix with -XX:MaxRAMPercentage=75.0 (not -Xmx = limit) plus leak repair if confirmed.
Common Mistakes & Pitfalls
Raising the memory limit without diagnosing root cause — fixes the symptom, hides a potential leak that will return at higher scale
Check your understanding
Answer these without looking back at the article.
- How do you copy a heap dump from a Kubernetes pod that has already been OOMKilled?
- What is a classloader leak and how does it cause Metaspace OOM?
- How do you use Eclipse MAT Leak Suspects to identify a leak in a Spring Boot app?
- When should you use Vertical Pod Autoscaler to size memory automatically?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.