Introduction to Java Garbage Collection
- Java Garbage Collection (GC) is the process of automatically managing memory.
- It helps in reclaiming memory occupied by objects that are no longer in use.
- Improves efficiency and prevents memory leaks.
Why Garbage Collection is Needed?
- Manual memory management is error-prone and can lead to memory leaks.
- GC helps prevent memory leaks and improves application performance.
- It ensures efficient utilization of memory.
Types of Java Garbage Collectors
- Serial Garbage Collector - Best for small applications.
- Parallel Garbage Collector - Uses multiple threads for garbage collection.
- CMS (Concurrent Mark-Sweep) Collector - Reduces GC pause times.
- G1 (Garbage First) Collector - Balances performance and memory efficiency.
- Other Variants like : ZGC, Epsilon, Shenondoah
Serial GC
Can be turned on using-XX:+UseSerialGC JVM option.
Parallel GC
Default in JDK 8.0
Concurrent Mark & Sweep (CMS)
Can still go in Stop-The-World(STW) mode ex: While initializing the initial marking of roots, unreachability check
Garbage First (G1)
The G1 GC is a low-latency, high-performance garbage collector introduced in Java 7 Update 4 and became the default GC in Java 9.
Key Features of G1 GC:
- Heap Partitioning: Instead of dividing the heap into fixed generations (like the old Parallel GC), G1 splits the heap into regions (young, old, and humongous regions).
- Predictable Pause Times: G1 aims to meet a user-defined pause time goal (e.g., -XX:MaxGCPauseMillis=200 means it will try to keep GC pauses under 200ms).
- Concurrent Processing: It performs most of its work concurrently, reducing stop-the-world (STW) pauses.
- Evacuating Collection: Instead of sweeping the whole heap, G1 moves live objects to new regions and frees up old ones, reducing fragmentation.
- Humongous Objects Handling: Large objects (greater than half of a region size) are stored in contiguous regions, avoiding excessive fragmentation.
Is G1 GC “Garbage”?
No! G1 is actually one of the best general-purpose garbage collectors in modern Java applications, especially for large heaps (4GB+ RAM). However, it may not be ideal for ultra-low-latency applications (e.g., high-frequency trading), where alternatives like ZGC or Shenandoah GC might be better
G1 can be enabled using the –XX:+UseG1GC flag. Default in JDK 9.0
Espilon GC
Epsilon GC is a pass-through, no-op garbage collector introduced in JDK 11. It allocates memory but never reclaims it, meaning it never performs garbage collection. Once the heap is full, the JVM immediately shuts down with an OutOfMemoryError (OOM).
Key Features of Epsilon GC
✅ Ultra-low GC overhead (since it does nothing)
✅ Good for performance testing & benchmarking (eliminates GC noise)
✅ Useful for very short-lived applications (where GC is unnecessary)
✅ Can be used in memory management experiments
When to Use Epsilon GC?
- Performance Testing: Ensures that GC isn’t affecting benchmark results.
- Memory Footprint Analysis: Helps analyze how memory is allocated.
- Short-lived Applications: Apps that exit before running out of memory.
- Custom Memory Management: If you manually handle memory, Epsilon won’t interfere.
java -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xmx2G MyApp
Downsides of Epsilon GC
❌ No actual garbage collection (memory fills up quickly)
❌ Not suitable for long-running applications
❌ Causes immediate OOM when memory is exhausted
Shenandoah GC
Shenandoah GC is an advanced low-latency, concurrent garbage collector introduced in JDK 12. It’s designed to reduce GC pause times, even for large heaps (up to terabytes of memory).
Key Features of Shenandoah GC
✅ Concurrent Compaction: Unlike G1, which compacts memory during stop-the-world (STW) pauses, Shenandoah performs compaction concurrently, reducing pause times.
✅ Predictable Low Latency: Keeps pause times below 10ms, even for large heaps (multi-gigabyte or terabyte-scale).
✅ Region-Based Heap Management: Similar to G1, but no separate young/old generations—all regions are treated equally.
✅ Concurrent Execution: Most of the work (marking, evacuation, compaction) is done while the application is running.
How Shenandoah GC Works
Concurrent Marking: Identifies live objects while the application is running.
Concurrent Evacuation: Moves objects to new regions without long STW pauses.
Concurrent Compaction: Defragments memory without stopping the world.
STW Finalization: Only short pauses for cleanup.
When to Use Shenandoah GC?
- Low-latency applications (financial systems, gaming, real-time analytics).
- Large heaps (hundreds of GBs to TBs).
- Applications where GC pauses impact performance.
- Cloud-native and containerized workloads (efficient and predictable behavior).
Downsides of Shenandoah GC
❌ Higher CPU usage (due to concurrent processing).
❌ Not ideal for small heaps (overhead isn’t worth it).
❌ Requires JDK 12+ (JDK 17+ recommended for best performance).
ZGC
Z Garbage Collector (ZGC) is a scalable, ultra-low-latency GC introduced in JDK 11 and became production-ready in JDK 15. It is designed to keep GC pause times below 1 millisecond, even with very large heaps (up to 16TB).
Key Features of ZGC
✅ Sub-1ms Pause Times: ZGC performs most of its work concurrently, keeping pause times under a millisecond, regardless of heap size.
✅ Handles Huge Heaps: Supports heap sizes from a few gigabytes (8GB) to 16TB.
✅ Concurrent Compaction: Unlike G1, which compacts memory during stop-the-world (STW) pauses, ZGC compacts memory while the application runs, eliminating long pauses.
✅ No Generational GC (Yet): As of JDK 17, ZGC doesn’t have separate young/old generations—it treats all objects the same. However, Generational ZGC (JDK 21+) introduces better performance.
✅ Pointer Coloring: Uses colored pointers for efficient object tracking, minimizing metadata overhead.
How ZGC Works
- Concurrent Marking: Identifies live objects while the application is running.
- Concurrent Relocation: Moves objects without stopping the application.
- Concurrent Remapping: Updates references to relocated objects on-the-fly.
- Minimal Stop-the-World (STW) Phases: Pauses are kept under 1ms, even for terabyte-scale heaps.
When to Use ZGC?
- Ultra-low-latency applications (e.g., high-frequency trading, gaming, real-time analytics).
- Massive heap sizes (8GB - 16TB).
- Cloud and containerized environments (efficient and scalable).
- Applications where long GC pauses are unacceptable.
Downsides of ZGC
❌ Higher CPU usage (due to concurrent processing).
❌ Not ideal for small heaps (<8GB) (Shenandoah or G1 might be better).
❌ Requires JDK 11+ (JDK 17+ recommended for best performance).
GC Type |
Avg. Pause Time |
Heap Size Suitability |
Compaction |
Use Case |
G1 GC |
10ms - 500ms |
4GB - 100GB | STW-based |
Balanced workloads |
Shenandoah | 1ms - 10ms | 4GB - 1TB+ | Concurrent | Low-latency apps |
ZGC | ~1ms | 8GB - 16TB | Concurrent | Ultra-low latency |
Generations in Java Garbage Collection
- Young Generation - Stores newly created objects - Minor GC occurs frequently here.
- Old Generation - Stores long-lived objects - Major GC runs less frequently but takes more time.
- Permanent Generation (Metaspace in Java 8+)
- Stores class metadata - Not affected by GC in the same way as heap objects.

Garbage Collection Algorithms
- Mark and Sweep - Marks and removes unused objects.
- Copying - Copies live objects to a new space and clears the old one.
- Reference Counting - Keeps track of object references.
- Generational GC - Divides memory into Young, Old, and Permanent generations.
- Frequent GC cycles can slow down
performance.
- Tuning GC parameters can optimize memory
usage.
- Choosing the right GC type based on
application requirements.
Best Practices for Memory
Management
- Avoid creating unnecessary objects.
- Use Weak References for cache management.
- Explicitly set objects to null when they are no
longer needed.
- Profile memory usage with tools like
VisualVM and JConsole.
Advantages of GC
- Makes code simple - developers only focus on business logic rather than memoory management
- Is memeory efficient - GC removes unreference objects from heap memory
Java GC Commands and JVM Options
- -XX:+UseSerialGC → Use Serial Garbage Collector.
- -XX:+UseParallelGC → Use Parallel Garbage
Collector.
- -XX:+UseG1GC → Use G1 Garbage Collector.
- -XX:+PrintGCDetails → Print detailed GC logs.
- -Xms:size -Xmx:size → Set initial and max heap
size.
- -XX:NewRatio=n → Ratio of Young to Old
Generation size.
- java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx8G MyApp -> to enable Shenandoah
- java -XX:+UseZGC -Xmx16G MyApp -> to Enable Z Garbage collector