While Java handles memory automatically via Garbage Collection (GC), high-performance engineering requires understanding the allocation path, reclamation barriers, and internal heap structures.
Most developers assume allocation happens on a global heap lock. In reality, the JVM uses Thread-Local Allocation Buffers (TLABs) to avoid contention.
The Generational Hypothesis states that most objects die young. Modern GCs use Write Barriers to track cross-generational references.
-XX:MaxTenuringThreshold) are moved to the Old Generation.| Feature | G1 GC (Balanced) | ZGC (Latency Focused) |
|---|---|---|
| Heap Structure | Regions (fixed size) | Regions (dynamic size) |
| Max Pause Time | Target-based (~200ms) | Sub-millisecond |
| Throughput | High | Medium (due to load barriers) |
| Best For | General apps, large heaps | Low-latency, huge heaps (>32GB) |
Problem: Application throughput degrades over 48 hours. jstat shows the Old Generation is steadily climbing despite frequent GCs.
# Watch GC stats every 1s
jstat -gcutil <pid> 1000
If O (Old Gen %) increases after every Full GC, you have a Memory Leak (retained references).
Using jcmd to identify which classes are hogging memory:
# Print top 20 classes by memory usage
jcmd <pid> GC.class_histogram | head -n 20
If a custom class (e.g., com.app.SessionCache) appears at the top, capture a heap dump for the Eclipse Memory Analyzer (MAT):
jcmd <pid> GC.heap_dump /tmp/dump.hprof
-Xmx, which can lead to OS-level OOMs.See Also: