What types of OutOfMemoryError exist?
4. MaxDirectMemorySize — NIO control 5. Monitor dmesg for OOM Killer 6. jcmd VM.metaspace for Metaspace analysis
Junior Level
OutOfMemoryError comes in different types — each points to its own problem:
| Type | What it means |
|---|---|
| Java heap space | Heap overflowed |
| GC overhead limit exceeded | GC runs constantly |
| Metaspace | Class metadata overflowed |
| Direct buffer memory | Memory outside Heap (NIO) |
| Unable to create new native thread | OS thread limit |
Middle Level
Java heap space
Cause: leak or small -Xmx
Solution:
1. -XX:+HeapDumpOnOutOfMemoryError
2. Analysis in MAT
3. Find leak or increase -Xmx
GC overhead limit exceeded
98% time on GC, < 2% freed
→ Application "froze" in infinite Full GC loop
Solution:
- Increase Heap
- Find leak
- Disable: -XX:-UseGCOverheadLimit (not recommended!)
Metaspace
Class metadata overflowed
Causes:
- Dynamic generation (Spring, CGLIB)
- ClassLoader leaks
Solution:
-XX:MaxMetaspaceSize=512m
jcmd <pid> VM.metaspace
Direct buffer memory
NIO memory outside Heap
Causes: Netty, ByteBuffer.allocateDirect()
Solution:
-XX:MaxDirectMemorySize=2g
Check Netty leaks
Unable to create new native thread
OS cannot create thread
Causes:
- ulimit -u reached
- RAM for stacks (-Xss) exhausted
Solution:
Decrease -Xmx (more RAM for stacks)
Check ulimit -u
Senior Level
Requested array size exceeds VM limit
Array > Integer.MAX_VALUE elements
→ Most often indicates a logic error. But legitimate cases exist: attempting to load a large file into memory entirely.
Compressed Class Space
Compressed Class Space — part of Metaspace for compressed class pointers (4 bytes instead of 8).
Limit: -XX:CompressedClassSpaceSize (1 GB default). Overflow → OOME, even if Metaspace has free space.
Map failed (Memory Mapped Files)
MappedByteBuffer.map() → error
→ vm.max_map_count reached
→ No virtual memory for mapping
Solution: sysctl -w vm.max_map_count=262144
Linux OOM Killer
NOT a Java error!
→ Container: limit < RSS
→ OS kills process via SIGKILL
→ No dumps, no logs!
Diagnostics:
dmesg | grep -i oom
→ "Out of memory: Kill process"
Summary Table
| Type | Where to look | Flag |
|---|---|---|
| Heap | Heap leaks | HeapDumpOnOOM |
| Metaspace | ClassLoader leaks | VM.metaspace |
| Direct buffer | Netty/NIO | NMT |
| Native thread | ulimit, -Xss | ps -Hu |
| GC overhead | Thrashing | GC Logs |
Best Practices
- HeapDumpOnOutOfMemoryError — mandatory
- NMT=detail for Native Memory
- MaxMetaspaceSize — limit for containers
- MaxDirectMemorySize — NIO control
- Monitor dmesg for OOM Killer
- jcmd VM.metaspace for Metaspace analysis
Senior Summary
- OOME type = first clue in investigation
- Heap space = Heap leaks
- Metaspace = ClassLoader leaks
- Direct buffer = NIO leaks (outside Heap)
- Native thread = OS limits
- OOM Killer = not a Java error (containers)
- NMT = Native Memory diagnostics
Interview Cheat Sheet
Must know:
Java heap space— Heap overflowed; solution: HeapDumpOnOOM + MAT analysis + find leak or increase -XmxGC overhead limit exceeded— 98% time on GC, < 2% freed; infinite Full GC loopMetaspace— class metadata overflowed; causes: dynamic generation (Spring, CGLIB), ClassLoader leaksDirect buffer memory— NIO memory outside Heap; Netty, ByteBuffer.allocateDirect(); solution: MaxDirectMemorySizeUnable to create new native thread— ulimit -u reached or RAM for stacks (-Xss) exhaustedRequested array size exceeds VM limit— array > Integer.MAX_VALUE; most often a logic error- Linux OOM Killer — NOT a Java error! Container: limit < RSS → OS kills via SIGKILL → no dumps
Common follow-up questions:
- How to distinguish JVM OOME from OS OOM Killer? — JVM OOME: stack trace in logs; OOM Killer:
dmesg | grep -i oom, process disappears without logs - What is Compressed Class Space OOME? — Part of Metaspace for compressed class pointers (1 GB limit); overflow → OOME, even if Metaspace is free
- Why does “Requested array size exceeds VM limit” happen? — Attempt to create array > Integer.MAX_VALUE elements; often a bug (loading large file entirely)
- How to diagnose OOM Killer in Kubernetes? —
dmesg | grep -i oom; Pod terminated (OOMKilled); solution: increase limit or reduce RSS
Red flags (DO NOT say):
- “I’ll disable
-XX:-UseGCOverheadLimitand the problem is solved” — this masks the problem; application will still crash with Heap space OOME - “OOM Killer is a Java bug” — it’s an OS decision; Java doesn’t control container limits
- “Direct buffer memory = part of Heap” — DirectByteBuffer allocates memory OUTSIDE Heap (
-Xmxdoesn’t affect it)
Related topics:
- [[19. What happens on OutOfMemoryError]]
- [[11. What is Metaspace (or PermGen)]]
- [[6. What is a memory leak in Java]]
- [[18. What are -Xms and -Xmx parameters]]
- [[21. What is a memory leak and how to detect it]]