On this page
Heap Tuning
Heap tuning configures how much memory the JVM allocates for object storage and how it is divided between generations. Proper sizing prevents OutOfMemoryError and minimizes GC pauses.
Heap Structure
┌─────────────────────────────────────────┐
│ Heap │
│ ┌──────────────┬─────────────────────┐ │
│ │ Young Gen │ Old Gen │ │
│ │ Eden|S0|S1 │ │ │
│ └──────────────┴─────────────────────┘ │
└─────────────────────────────────────────┘
+ Metaspace (off-heap, class metadata)
+ Thread stacks, code cache, direct memory
Key JVM Flags
# Fixed heap size (recommended for production)
-Xms4g -Xmx4g
# Young generation size
-Xmn1g
# or ratio: -XX:NewRatio=2 (Old:Young = 2:1)
# Metaspace (replaces PermGen since Java 8)
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
# Stack size per thread
-Xss1m
# Direct memory (NIO buffers)
-XX:MaxDirectMemorySize=512m
Sizing Guidelines
| Application type | Heap size | Notes |
|---|---|---|
| Small REST API | 512m–1g | Low object allocation |
| Medium web app | 2g–4g | Moderate caching |
| Data processing | 8g–32g | Large in-memory datasets |
| Microservice | 256m–512m | Many small JVMs |
Rule of thumb: Set -Xms equal to -Xmx to avoid heap resize pauses at startup.
Container-Aware Settings
# Respect container memory limits (Java 10+)
-XX:MaxRAMPercentage=75.0
-XX:InitialRAMPercentage=75.0
# Exit on OOM (let orchestrator restart)
-XX:+ExitOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/var/log/heapdump.hprof
OutOfMemoryError Types
| Error | Cause | Fix |
|---|---|---|
Java heap space |
Objects exceed heap | Increase -Xmx, fix memory leak |
Metaspace |
Too many classes loaded | Increase metaspace, check class loaders |
Unable to create native thread |
Too many threads | Reduce threads, increase -Xss or ulimit |
Direct buffer memory |
NIO buffers exhausted | Increase MaxDirectMemorySize |
GC overhead limit exceeded |
GC spends >98% time, frees <2% | Increase heap or fix leak |
Analyzing Heap Dumps
# Generate heap dump
jcmd <pid> GC.heap_dump /tmp/heap.hprof
# Or on OOM (automatic)
-XX:+HeapDumpOnOutOfMemoryError
# Analyze with Eclipse MAT or VisualVM
jhat /tmp/heap.hprof # basic HTML report
Look for:
- Leak suspects — objects retaining unexpected memory
- Duplicate strings — inefficient string storage
- Large collections — unbounded caches or lists
Monitoring Heap Usage
# Live heap summary
jcmd <pid> GC.heap_info
# JVM stats
jstat -gc <pid> 1000 10 # GC stats every 1s, 10 times
# Via Actuator (Spring Boot)
GET /actuator/metrics/jvm.memory.used
GET /actuator/metrics/jvm.memory.max
Best Practices
- Always set
-Xms=-Xmxin production - Use
MaxRAMPercentagein containers instead of fixed sizes - Enable heap dump on OOM for post-mortem analysis
- Profile before tuning — don’t guess heap sizes
- Monitor GC logs alongside heap metrics