Garbage Collection
Java Garbage Collection — how GC works, G1GC vs ZGC, tuning for production, and diagnosing GC-related performance issues.
Last reviewed: January 2025
🔍 What Is It?
Generational Hypothesis:
Most objects die young. GC is optimized for this:
- →Young Generation (Eden + S0 + S1): new objects allocated here; Minor GC cleans it frequently and fast
- →Old Generation (Tenured): objects that survived multiple Minor GCs; Major GC cleans it rarely but slowly
GC Algorithms:
Serial GC (-XX:+UseSerialGC)
- →Single-threaded; Stop-The-World for all collections
- →For single-CPU machines and small heaps only
Parallel GC (-XX:+UseParallelGC)
- →Multi-threaded; still Stop-The-World
- →Default in Java 8; good throughput, higher pauses
G1GC (-XX:+UseG1GC)
- →Default in Java 9+
- →Divides heap into equal-sized regions
- →Concurrent marking with short STW pauses
- →Targets pause time goal (-XX:MaxGCPauseMillis=200)
- →Good for heaps 4GB–32GB
ZGC (-XX:+UseZGC)
- →Java 15+ production-ready; sub-millisecond STW pauses
- →Fully concurrent — almost no STW
- →Works for heaps from 8MB to 16TB
- →Best for latency-sensitive applications
Shenandoah (-XX:+UseShenandoahGC)
- →Similar to ZGC; available in OpenJDK builds
- →Sub-millisecond pauses; fully concurrent
🎯 Why Do We Need It?
Without GC, developers must manually free memory (like C/C++):
- →malloc() to allocate; free() to release
- →Forgetting free() = memory leak
- →Double-free() = crash
- →Use-after-free = security vulnerability
Java's GC eliminates these entire categories of bugs. The tradeoff: GC pauses and overhead. Modern GCs have reduced this tradeoff to near-zero for most applications.
🏗️ What Happens in Real Projects?
GC tuning is a real production concern:
- →High GC frequency = too many short-lived objects (fix: reduce object allocation)
- →Long GC pauses = old generation too full (fix: increase heap, tune GC)
- →GC CPU overhead > 5% = GC working too hard (fix: heap tuning, reduce allocation)
- →Memory leak = heap grows until OOM (fix: heap dump analysis)
⚙️ How It Works
Minor GC (Young Generation):
- Objects allocated in Eden
- When Eden is full, Minor GC runs
- Live objects copied to Survivor space (S0)
- Next Minor GC: live objects from Eden + S0 copied to S1
- After N collections (default: 15), promoted to Old Generation
- Eden and empty Survivor space cleared
Major/Full GC (Old Generation):
- Triggered when Old Generation fills up
- Mark all live objects (may be concurrent in G1/ZGC)
- Compact/collect garbage
- Stop-The-World pause (shorter in G1, near-zero in ZGC)
GC Roots (starting points for reachability analysis):
- →Local variables on stack
- →Static fields
- →JNI references
- →Active threads
💻 Example
GC Tuning and Monitoring — How to tune and monitor GC in production Java applications.
🤔 Common Confusions
❓ Does calling System.gc() force garbage collection?
System.gc() is a hint to the JVM to run GC — it does not guarantee it will happen, and the JVM may ignore it. Calling it explicitly is almost never the right solution. If you are having memory issues, fix the root cause (memory leak, heap too small) rather than trying to force GC.
❓ What is a Stop-The-World pause?
A Stop-The-World (STW) pause freezes all application threads so the GC can safely inspect the heap without objects moving around. During STW, your application is completely unresponsive. Modern GCs (G1, ZGC) minimize STW by doing most work concurrently while the application runs. ZGC achieves sub-millisecond STW even on terabyte heaps.
❓ Why does increasing heap size sometimes make GC worse?
A larger heap means more objects to scan during Full GC, which means longer pauses. With a 1GB heap, a Full GC might take 1 second. With a 32GB heap, it might take 30 seconds. G1GC and ZGC are designed for large heaps. For G1GC, keep heap under 32GB. For larger heaps, use ZGC.
🚨 Common Production Issues
GC overhead limit exceeded — GC spending more than 98% of time collecting less than 2% of heap. Usually a memory leak. Analyze with heap dump.
Promotion failure in G1GC — Old Generation fills up during Minor GC, triggering Full GC. Increase heap or tune -XX:InitiatingHeapOccupancyPercent.
Humongous allocations in G1GC — objects larger than 50% of region size go directly to Old Generation, bypassing Young. Tune -XX:G1HeapRegionSize or reduce large object allocations.
✅ Best Practices
Use G1GC for most applications (default Java 9+); ZGC for latency-sensitive or large heaps.
Set -Xms = -Xmx to prevent heap resizing pauses.
Enable GC logging in production: -Xlog:gc*:file=gc.log:time,uptime
Monitor GC pause time and frequency — alert when pauses exceed SLA.
Reduce object allocation in hot paths — the best GC is no GC.
Use -XX:+HeapDumpOnOutOfMemoryError for automatic heap dump on OOM.
🏛️ Architect's Note
GC tuning is the last resort, not the first. The best way to reduce GC pressure is to allocate fewer objects: use primitives instead of wrappers, reuse objects, use streaming instead of materializing large collections, and avoid unnecessary String concatenation in loops. Profile your application's allocation rate with JFR (Java Flight Recorder) before tuning GC settings.
💬 Frequently Asked Questions
🎯 Key Takeaways
🔗 Related Topics
🎯 Practice this topic in interviews
Core Java Interview Prep
Practice interview questions that connect directly to this technology track.
↗ Where this topic fits
Core Java Technology Guide
Return to the Core Java learning hub.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Sources
Sources / References
Use these Core Java references to verify the concept in official docs and continue into the most relevant SplashRide pages.
Official documentation
Related SplashRide pages
SplashRide Core Java learning path
Browse the full Core Java topic collection and learning order on SplashRide.
Core Java Interview Prep
Practice Core Java interview questions and scenario-based answers.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Heap & Stack
Java memory model — Heap vs Stack, what lives where, and how understanding this prevents OutOfMemoryErrors and StackOverflowErrors.
JVM
Deep dive into the Java Virtual Machine — class loading, memory model, JIT compilation, and how the JVM turns bytecode into running software.