The post is a curated list of various garbage collectors available in java VM. We will also explore various use-cases for the respective collectors.
Garbage Collection is one of the most appreciated features of the Java programming language, making it suitable for all kinds of applications. The ability to automatically recover the previously allocated memory, which is no longer in use, allows the Java programmers to focus on the core business logic - a big selling point compared to other object-oriented languages like C++, where the programmer must manually manage the memory.
In most cases, the GC process can be categorized into the following:
Following is the list of various Garbage Collectors that are available in Java. Each of these has its strong areas. Depending on the java version in use, we should choose a GC strategy best suited for the specific use case. The GC strategy should consider at least the following:
You can also refer to this link for a list of various flags and arguments available to fine-tune the GC setup.
Please note that this is NOT an in-depth detailed post on each collector and only lists the available options.
As the name suggests, the Serial garbage collector is a single-threaded model which halts all the application threads (Stop the world - STW event) before triggering the garbage collection. It uses the simplest form of mark-sweep-compact stages and works as a generational (young and tenured) garbage collector.
To enable serial GC, we can use the following argument:
Parallel GC attempts to improve the Serial GC performance and throughput by using multiple threads, specified via a command-line option
–XX:ParallelGCThreads=n for young generation GC cycles. However, for the tenured (old) generation, it still uses Serial Mark and Compact algorithm.
Also, like serial GC, it issues the STW event before the GC cycles can begin to reclaim the unused memory.
It is suitable for applications with small to medium-sized datasets running on multi-core machines. If peak application performance is the priority and there are no pause time requirements or pauses of 1 second or longer are acceptable, Parallel GC can be a good choice.
To enable parallel GC, pass the following argument:
An extension to parallel GC, Parallel Old GC uses multiple threads for both tenured and the young generation.
To use parallel Old GC, pass the following argument:
Deprecated as of java9 and entirely dropped in java14, the Concurrent Mark Sweep (CMS) collector is a mostly concurrent collector using multiple threads for the GC process. Unlike other collectors mentioned above, it is meant for applications that allow CPU sharing between application threads and GC threads.
CMS collector trigger STW event in following two cases:
If response time is more important than overall throughput and garbage collection pauses must be shorter, CMS is the suggested choice of GC collector. To use CMS collector, provide the following argument:
The Garbage first GC - also known as G1GC, is the most commonly used garbage collector for various applications. It can be termed as a universal collector providing a balance between latency and throughput with features to meet basic requirements for most use-cases (large datasets, batch processing, transactional data, etc.).
Introduced in Java7 and made default in java9, G1GC is a mostly-concurrent low-pause collector that will provide a better overall experience, for most users, than a throughput-oriented collector such as the Parallel GC. Moreover, it deploys multiple techniques to achieve the said goals.
G1 splits the heap into virtual young and old generations with space reclamation efforts concentrating on the young generation as it is most efficient.
To keep STW pauses short, G1 performs space recovery incrementally in steps and parallel. Java 8u20 added another enhancement that allows identification and cleanup of duplicate String instances by referencing a single
char globally. This can be enabled by passing the following argument:
-XX:+UseStringDeduplication This feature can help to reduce the overall heap usage by up to 10%.
Although G1GC is enabled by default, you can explicitly enable it by providing
-XX:+UseG1GC a VM argument.
Java11 introduces a new no-op collector known as Epsilon Collector that handles memory allocation but does NOT implement any actual memory reclamation mechanism. In other words, it will allocate memory, as required when new objects are instantiated, but does not reclaim any space consumed by unreferenced objects.
This serves the following use cases (not limited to):
In the absence of any other GC mechanism, the JVM will shut down once the available memory is exhausted.
This is an experimental feature and can be enabled by passing
The Z garbage collector was introduced as an experimental feature in Java 11. The same is now available as a production-ready product post Java15. It is a low latency, high throughput collector capable of handling datasets from 4 terabytes to 16 terabytes. It divides the heap space into logical sections known as regions which unlike G1GC, can be of different sizes.
It handles most of the GC tasks concurrently without stopping the execution of application threads for more than a few milliseconds. Additionally, pause times are independent of the heap size used, making it a suitable candidate for low latency applications.
ZGC is based on the concept of colored pointers, which is a technique that stores information in the unused bits of 64bit pointer/references itself (ZGC is not available on x32 platforms). This is possible as 64bits can reference a lot more address spaces than a system can realistically have. In addition to this, ZGC uses load barriers to keep track of heap usage.
ZGC can be enabled using
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC ExperimentalVMOptions flag is not required for ZGC post v15.
Introduced in Java12 as an experimental feature and marked as production-ready in Java15, Shenandoah, a regional collector, aims to reduce GC pause times by doing evacuation work concurrently with the running Java threads. Pause times with Shenandoah are independent of the heap size, meaning you will have the same consistent pause times whether your heap is 200 MB or 200 GB.
Unlike ZGC, Shenandoah is also available on x86_32 platforms (ARM32 is in dev at the time of writing this post). The collector can be enabled using
That is all for this post. Next, I hope to write detailed posts on the individual collectors explaining the respective implementations. If you want to share any feedback, please drop me an email, or contact me on any social platforms. I’ll try to respond at the earliest. Also, please consider subscribing for regular updates.