Let’s dive into the various types of garbage collectors available in Java and lay out a side-by-side comparison to help you choose the right one for your workload.
Garbage collection is an essential pillar of Java’s memory management, silently reclaiming unused memory and keeping your application healthy. With each new edition of the Java platform, OpenJDK introduces refinements to how garbage collectors work, aiming for better performance, reduced latency, and improved scalability.
At its core, a garbage collector (GC) frees up memory by automatically removing unused objects, sparing developers the burden of manual memory management. Different applications have different requirements—some demand lightning-fast throughput, others need minimal pause times, and some are designed for massive heap sizes. Java’s GC options have grown to accommodate these diverse needs.
A tour of Java’s garbage collectors
Let’s look at the main types of garbage collectors available in OpenJDK and how they fit into today’s Java ecosystem.
Serial GC
Serial GC is the simplest of the bunch, designed for single-threaded environments. It performs all garbage collection tasks in a single thread, making it suitable for small applications or embedded devices where resources are limited. While its implementation is straightforward, its stop-the-world pauses aren’t ideal for large-scale or interactive applications.
Parallel GC (Throughput Collector)
Parallel GC, sometimes called the Throughput Collector, utilises multiple threads to speed up the garbage collection process. It’s optimised for throughput, meaning it tries to maximise the amount of work done in a given time, even if that means longer pause times. This collector is often used for applications running on multicore processors that can afford occasional interruptions.
Concurrent Mark Sweep (CMS) GC
CMS was designed to minimise pause times by performing most of its work concurrently with the application threads. It marks live objects while the application is running and sweeps away the dead ones. However, CMS can suffer from fragmentation and isn’t recommended for future projects since it’s been deprecated and removed from newer Java versions.
Garbage First (G1) GC
G1 GC is a modern collector that strives to balance throughput and low latency. It divides the heap into regions and prioritises areas with the most garbage to collect first. G1 is adaptive, tuning its behaviour based on pause-time goals you set. It’s the default collector for most contemporary Java applications and continues to evolve with each Java release.
Epsilon GC
Epsilon is a ‘no-op’ garbage collector. It doesn’t reclaim memory—it simply allocates until the process runs out of heap space. This collector is useful for performance testing or scenarios where memory management is handled externally.
Z Garbage Collector (ZGC)
ZGC is a scalable, low-latency collector designed to handle massive heaps (think multi-terabyte scale) with minimal pauses. It carries out most of its work concurrently, pausing application threads only briefly. ZGC is suitable for cloud workloads, large in-memory databases, and applications that cannot tolerate significant interruptions.
Shenandoah GC
Like ZGC, Shenandoah is focused on ultra-low pause times, even as heap sizes scale into terabytes. Shenandoah performs concurrent compaction, further reducing pause times compared to traditional collectors. It’s particularly attractive for applications demanding high responsiveness.
| GC type | Threading model | Pause time | Heap size support | Throughput | Fragmentation handling | Recommended for | Concurrent
compaction |
| Serial GC | Single thread | High (stop-the-world) | Small | Low | Poor | Small apps, single-core systems | No |
| Parallel GC | Multi-threaded | Moderate | Medium-Large | High | Moderate | Batch processing, multicore systems | No |
| CMS GC | Multi-threaded (concurrent) | Low | Medium-Large | Moderate | Poor (fragmentation possible) | Low-latency apps (deprecated) | No |
| G1 GC | Multi-threaded (concurrent + parallel) | Configurable (low to moderate) | Large | High | Good (region-based) |
General purpose, latency-sensitive apps | Partial |
| Epsilon GC | Single thread | None (no collection) | Small-Medium | Highest (no GC overhead) | N/A | Testing, custom memory management | No |
| ZGC | Multi-threaded (concurrent) | Very low (<2ms) | Huge (>4TB) | High | Excellent | Large heaps, real-time, cloud | Yes |
| Shenandoah GC | Multi-threaded (concurrent) | Very low (<10ms) | Huge (>4TB) | High | Excellent | Large heaps, low latency | Yes |
What’s new in Java 25 garbage collection?
Java 25 introduces several notable enhancements to garbage collection:
ZGC improvements
ZGC now features even shorter pause times and better support for thread-local allocation buffers (TLABs), leading to more predictable latencies for real-time applications.
Shenandoah enhancements
Shenandoah now supports improved handling of large objects and more efficient concurrent compaction, which reduces heap fragmentation and boosts allocation performance.
G1 adaptive tuning
G1 GC introduces new adaptive heuristics to better balance throughput and pause time, especially in workloads that fluctuate between bursty and steady-state memory allocation patterns.
Unified logging
Java 25 brings unified and more granular GC logging, making it easier for developers to analyse memory behaviour and tune GC settings for their specific needs.
Better native memory tracking
Enhanced monitoring tools now allow for more accurate tracking of native memory usage alongside heap consumption, which helps in diagnosing leaks and optimising performance.
Recommended command-line usage
Here are the recommended scenarios for each garbage collector in Java 25 and its command-line usage.
Serial GC
Recommended scenario: This garbage collector is best for small apps with limited CPU resources.
Command-line usage:
java -XX:+UseSerialGC -jar test-application-name.jar
Parallel Garbage Collector
Recommended scenario: Parallel GC is suitable for any multi-threaded application where throughput is a primary consideration.
Command-line usage:
java -XX:+UseParallelGC -jar test-application-name.jar
Concurrent Mark Sweep (CMS) Garbage Collector
Recommended scenario: CMS GC works mainly on the old (tenured) generation and uses multiple threads to mark and sweep unused objects.
Command-line usage:
java -XX:+UseConcMarkSweepGC -jar test-application-name.jar
G1 (Garbage First) Garbage Collector
Recommended scenario: This option is most suitable for applications that require consistent pause times and manage large memory heaps.
Command-line usage:
java -XX:+UseG1GC -jar test-application-name.jar
Z Garbage Collector (ZGC)
Recommended scenario: This GC is designed for applications requiring minimal pause times and large heaps.
Command-line usage:
java -XX:+UseZGC -jar test-application-name.jar
Shenandoah Garbage Collector
Recommended scenario: This GC is suitable for low-latency applications with large heaps.
Command-line usage:
java -XX:+UseShenandoahGC -jar test-application-name.jar
Epsilon Garbage Collector
Recommended scenario: Epsilon is suitable for performance testing and benchmarking scenarios where memory reclamation is not required.
Command-line usage:
java -XX:+UseEpsilonGC -jar test-application-name.jar
The table above summarises the key characteristics of each garbage collector discussed above. This should help you match a collector to your specific application needs.
Java’s garbage collectors have evolved to meet a wide variety of demands, from tiny embedded systems to sprawling cloud services that require heaps spanning terabytes. Java 25 continues this tradition, refining the latest collectors to be even more responsive and powerful. As you select a GC for your next Java project, weigh your application’s needs for performance, pause time, and heap size support, and don’t forget to keep an eye on the latest improvements—these can make a real difference in your application’s stability and responsiveness.
Disclaimer: This article expresses his views and not of the organisation he works in.














































































