Java: Serial GC, Parallel GC, G1 GC, ZGC, and Shenandoah

19 Jul 2026, Updated: 20 Jul 2026 9 min read
2
In this article, we explore the major garbage collectors available in modern JVMs, including Serial GC, Parallel GC, G1 GC, Z Garbage Collector (ZGC), and Shenandoah GC.

Java GC Evolution

As Java applications evolved from small desktop programs to massive cloud-native systems handling terabytes of memory, garbage collectors also evolved to address increasingly demanding performance requirements.

Earlier collectors emphasized simplicity and throughput, while modern collectors focus on reducing pause times and supporting very large heaps.

The evolution of Java garbage collectors can be summarized as follows:
Garbage Collector Key Improvement Primary Goal
Serial GC Single-threaded garbage collection Simple collector for small heaps and client applications
Parallel GC Multiple GC threads Maximize throughput on multi-core systems
CMS (Concurrent Mark Sweep) Concurrent garbage collection Reduce application pause times
G1 GC Region-based heap with predictable pauses Balance throughput and low latency
ZGC Ultra-low latency concurrent collector Keep pause times to a few milliseconds even with very large heaps
Shenandoah GC Nearly all GC work performed concurrently Minimize pauses regardless of heap size

Serial Garbage Collector (Serial GC)

The Serial Garbage Collector (Serial GC) is the simplest garbage collector provided by the JVM.

It uses a single thread to perform all garbage collection activities and temporarily pauses all application threads while memory is being reclaimed.

Because only one thread performs garbage collection, Serial GC has minimal overhead and performs well for applications with small heaps and limited CPU resources.

However, as heap sizes grow, the application pause times become longer, making it unsuitable for large server applications.

A simplified Serial GC lifecycle consists of:

1. The application is running normally.
2. A garbage collection event is triggered.
3. All application threads are paused (Stop-The-World).
4. A single GC thread performs garbage collection.
5. The application resumes execution.

Serial GC does not scale with multiple CPU cores because it performs all garbage collection work using a single thread, making it a poor choice for latency-sensitive server applications where minimizing pause times and maximizing throughput are important.

Serial GC can be enabled by starting the JVM with the -XX:+UseSerialGC option.
java -XX:+UseSerialGC MyApplication

Parallel Garbage Collector (Parallel GC)

The Parallel Garbage Collector (Parallel GC), also known as the Throughput Collector, was designed to maximize application throughput by performing garbage collection using multiple threads.

Like Serial GC, it pauses all application threads during garbage collection.

However, instead of relying on a single GC thread, it uses multiple worker threads to reclaim memory in parallel, significantly reducing garbage collection time on multi-core systems.

A simplified Parallel GC lifecycle consists of:

1. The application is running normally.
2. A garbage collection event occurs.
3. All application threads are paused.
4. Multiple GC threads reclaim memory simultaneously.
5. The application resumes execution.

Parallel GC performs garbage collection faster than Serial GC by using multiple threads on multi-core systems.

It is efficient for CPU-intensive workloads but still causes Stop-The-World pauses, making it less suitable for applications requiring consistently low response times.

Parallel GC can be enabled by starting the JVM with the -XX:+UseParallelGC option.
java -XX:+UseParallelGC MyApplication

Concurrent Mark Sweep (CMS) Garbage Collector

The Concurrent Mark Sweep (CMS) collector was introduced to reduce application pause times by performing most garbage collection work concurrently with application threads.

Unlike Serial GC and Parallel GC, CMS does not perform all of its work during Stop-The-World pauses. Instead, much of the marking and sweeping occurs while the application continues running, resulting in significantly shorter pauses.

A simplified CMS lifecycle consists of:

1. Initial Mark (Stop-The-World).
2. Concurrent Mark.
3. Remark (Stop-The-World).
4. Concurrent Sweep.

CMS (Concurrent Mark Sweep) performs most garbage collection work concurrently with application threads, resulting in much shorter pause times than Serial GC and Parallel GC.

However, it does not normally compact memory, which can lead to heap fragmentation, and its concurrent execution increases CPU usage. CMS was deprecated in Java 9 and removed in Java 14.

Today, G1 GC has largely replaced CMS for these workloads.

CMS (Concurrent Mark Sweep) can be enabled by starting the JVM with the -XX:+UseConcMarkSweepGC option.

Note: This option is available only up to Java 13. Since CMS was removed in Java 14, the option is no longer supported in Java 14 and later.

G1 Garbage Collector (G1 GC)

The Garbage-First (G1) Garbage Collector was introduced to provide a better balance between throughput and low pause times.

Unlike earlier collectors that divided the heap into fixed contiguous Young and Old generations, G1 divides the heap into many equally sized regions, allowing it to collect only the regions containing the most garbage.

This region-based design enables G1 to perform garbage collection incrementally, resulting in more predictable pause times while maintaining high overall application throughput.

Starting with Java 9, G1 GC became the default garbage collector for the HotSpot JVM.

Instead of treating the heap as one large Young Generation and one large Old Generation, G1 organizes it into hundreds or even thousands of regions.

Each region can dynamically serve one of the following purposes:

- Eden Region – Stores newly created objects.
- Survivor Region – Stores objects that survive Young Garbage Collections.
- Old Region – Stores long-lived objects promoted from the Young Generation.
- Humongous Region – Stores very large objects that occupy one or more contiguous regions.
- Free Region – Available for future object allocation.

This allows the JVM to reclaim memory from selected regions instead of scanning the entire heap.

How G1 GC Works

G1 continuously monitors heap usage and identifies the regions containing the largest amount of reclaimable memory, known as garbage-first regions. A simplified G1 GC lifecycle consists of:

1. Allocate new objects in Eden regions.
2. Perform Young Garbage Collections as Eden fills up.
3. Mark live objects concurrently across the heap.
4. Identify regions containing the most reclaimable garbage.
5. Perform Mixed Garbage Collections, collecting both Young and selected Old regions.
6. Compact live objects while reclaiming unused regions.

Unlike CMS, G1 performs memory compaction during normal operation, preventing heap fragmentation.

Young GC vs Mixed GC

G1 performs two primary types of garbage collection.

Young GC

A Young GC collects only the Young Generation regions, including Eden and Survivor regions. This occurs frequently and is optimized for fast memory reclamation.

Mixed GC

After a concurrent marking cycle, G1 performs Mixed Garbage Collections. These collections reclaim memory from:

- Young Generation regions
- Selected Old Generation regions containing large amounts of garbage

Instead of collecting the entire Old Generation at once, G1 incrementally reclaims the regions that provide the greatest benefit.

G1 GC performs concurrent marking of live objects to reduce application pause times. It efficiently manages large heaps while providing predictable garbage collection pauses.

However, G1 GC is more complex than Serial GC and Parallel GC. It also may not achieve the ultra-low pause times provided by ZGC or Shenandoah GC.

Although G1 GC is the default collector in modern JVMs, it can be explicitly enabled if required.
java -XX:+UseG1GC MyApplication 

Z Garbage Collector (ZGC)

The Z Garbage Collector (ZGC) was designed for applications requiring extremely low latency, even when managing very large heaps.

Unlike earlier collectors, ZGC performs nearly all garbage collection work concurrently with application threads.

As a result, application pause times remain extremely smallβ€”typically measured in milliseconds, regardless of heap size.

Instead of stopping the application to process large portions of the heap, ZGC performs:

- Concurrent marking.
- Concurrent relocation of objects.
- Concurrent reference updates.

Only a few brief synchronization pauses remain, making pause times largely independent of heap size.

ZGC performs both garbage collection and memory compaction concurrently, resulting in extremely short pause times. It scales efficiently on multi-core systems and supports heap sizes ranging from a few gigabytes to multiple terabytes.

However, its concurrent execution requires additional CPU resources. ZGC can be enabled by starting the JVM with the -XX:+UseZGC option.

java -XX:+UseZGC MyApplication

Shenandoah Garbage Collector

The Shenandoah Garbage Collector is a low-latency garbage collector developed by Red Hat. Like ZGC, it performs most garbage collection work concurrently with application threads, minimizing Stop-The-World (STW) pauses.

Unlike traditional collectors that pause the application to move live objects, Shenandoah performs concurrent compaction, allowing object relocation while the application continues running. As a result, pause times remain short even as heap sizes increase.

A simplified Shenandoah collection cycle consists of:

1. Initial Mark (brief Stop-The-World).
2. Concurrent Mark.
3. Concurrent Evacuation (object relocation).
4. Concurrent Reference Update.
5. Final Cleanup.

Because nearly all of these phases execute concurrently, application pauses remain very short.

Shenandoah GC performs both garbage collection and object compaction concurrently, minimizing application pause times. However, its concurrent execution results in higher CPU usage than throughput-oriented collectors.

Shenandoah GC can be enabled by starting the JVM with the -XX:+UseShenandoahGC option.
java -XX:+UseShenandoahGC MyApplication

Comparison of Garbage Collectors

Each garbage collector is designed with different goals in mind. Some maximize throughput, while others minimize pause times.
Garbage Collector GC Threads Pause Times Throughput Best For
Serial GC Single High Moderate Small desktop and embedded applications
Parallel GC Multiple High Highest Batch processing and throughput-oriented applications
CMS (Deprecated) Multiple Low High Legacy low-latency applications
G1 GC Multiple Low High General-purpose server applications
ZGC Multiple Very Low High Large heaps and ultra-low latency systems
Shenandoah GC Multiple Very Low High Large, latency-sensitive applications

Final Notes

Modern JVMs provide multiple garbage collectors, each optimized for different performance goals.

While Serial GC and Parallel GC emphasize simplicity and throughput, G1 GC offers an excellent balance between throughput and predictable pause times.

For applications requiring extremely low latency, ZGC and Shenandoah GC minimize pause times by performing most garbage collection work concurrently with application execution.
Nagesh Chauhan

Nagesh Chauhan

Principal Software Engineer β€’ Java β€’ Python β€’ Distributed Systems β€’ AI/ML

Principal Software Engineer with 14+ years of experience designing and delivering large-scale distributed systems, cloud-native applications, and AI-powered platforms.

Passionate about solving complex engineering problems using strong data structures and algorithms, along with expertise in Java, Spring Boot, Python, System Design, Microservices, Cloud, Kafka, Elasticsearch, and Generative AI.

Share this Article

πŸ’¬ Comments

Join the Discussion