Observability & Performance Tuning
JVM Tuning for Spring Boot — Heap, GC, and Memory Settings
Configuring garbage collectors, setting maximum heap limits, and avoiding memory leaks.
Interview: JVM runtime memory management. Expect questions on heap vs non-heap allocations, garbage collection algorithms (G1GC vs ZGC), and setting memory limits inside containerized environments.
Introduction
Running a Java application inside a resource-constrained environment without configuring the JVM can cause instability. If you do not configure heap limits and garbage collection behaviors, the JVM will allocate resources based on host settings, leading to performance issues or container terminations.
Optimizing JVM performance requires sizing the memory footprint (Heap vs Metaspace) and selecting a **Garbage Collector** matching your latency requirements.
Why It Matters
Tuning JVM memory settings prevents Out-Of-Memory (OOM) crashes, reduces garbage collection pause times (stop-the-world events), and optimizes application startup speeds.
Comparing Garbage Collectors
Modern JDK versions include three primary garbage collection algorithms:
- G1GC (Garbage-First): The default collector since Java 9, designed for multi-gigabyte heaps. It divides the heap into regions, minimizing pause times while maintaining high throughput.
- ZGC (Z Garbage Collector): A low-latency collector designed for large heaps. It executes garbage collection tasks concurrently with application threads, limiting pause times to under a millisecond.
- SerialGC: A single-threaded collector designed for resource-constrained environments (e.g. containers with under 512MB RAM). It reduces CPU usage at the cost of longer garbage collection pauses.
Practical Example
Here is an example command containing production-ready JVM tuning parameters:
Quick Quiz
Q1: Which Garbage Collector should you choose to achieve low, sub-millisecond pause times for high-throughput REST APIs running on large memory pools?
A) SerialGC
B) G1GC
C) ZGC
D) ParallelGC
Answer: C — ZGC executes garbage collection concurrently with application threads, keeping pause times under a millisecond even on multi-gigabyte heaps.
Scenario-Based Challenge
Production Scenario:
Your Spring Boot API experiences periodic response timeouts under load. You check GC metrics and find the G1GC algorithm is triggering 3-second Stop-The-World pause sweeps. How do you tune the garbage collector to resolve these timeouts?
View Solution
To optimize G1GC pause times:
1. **Set Max GCPause Goal:** Configure -XX:MaxGCPauseMillis=200 to prioritize pause-time goals. G1GC will adjust region sizing to target this pause limit.
2. **Adjust Heap Occupancy Threshold:** Decrease the occupancy threshold using -XX:InitiatingHeapOccupancyPercent=40 (defaults to 45) to trigger garbage collection runs earlier, avoiding full stop-the-world sweeps.
3. **Increase Metaspace Limit:** Set Metaspace limits (e.g. -XX:MetaspaceSize=256m) to prevent G1GC from initiating garbage collection runs simply to resize metaspace areas during startup.
Interview Questions
1. What is the difference between Heap and Metaspace memory allocations in the JVM?
Heap memory stores runtime objects created by the application, which is managed by the garbage collector. Metaspace stores class metadata, method structures, and reflection information, which is allocated from native memory and grows dynamically by default unless capped by the MaxMetaspaceSize argument.
Production Considerations
Always configure the JVM to generate heap dumps during failures using the -XX:+HeapDumpOnOutOfMemoryError argument. This saves a binary memory dump to analyze memory leak stack traces during outages.