Week 131 — How can one set the garbage collector used by a Java application?
Question of the Week #131
How can one set the garbage collector used by a Java application?
8 Replies
The JVM comes with different garbage collectors for different situations. SerialGC is a low-footprint GC, ParallelGC is a high-throughput GC, G1 tries to balance throughput and latency and ZGC (as well as Shenandoah) is a low-latency GC.
By default, it uses G1 on most systems with newer JDKs but this can be changed using JVM arguments.
- Starting Java with
-XX:+UseSerialGC
uses the serial GC. This garbage collector pauses the application for GC work and performs its work in a single thread.
- Adding -XX:+UseParallelGC
to the JVM arguments configures it to use the parallel GC. This garbage collector pauses the application for GC work and performs its work in multiple threads.
- Running Java with -XX:+UseG1GC
uses the G1 ("garbage first") collector. This GC does some of its work while the application is running but still requires pauses for some of its GC work.
- The -XX:+UseZGC
option tells the JVM to use ZGC for garbage collection. This GC only pauses the application for synchronization and not for GC work. It ensures that these pauses stay below 1ms.
- The Shenandoah GC can be enabled with -XX:+UseShenandoahGC
on some JVMs. Similar to G1, this is a concurrent low-pause time GC but it is not available with every JDK.
JVM options like these should be added as command-line arguments to the java
command before the main class or -jar
. For example, java -XX:+UseZGC com.example.myproject.MyMainClass
or java -XX:+UseZGC -jar myjar.jar
activates ZGC while java com.example.myproject.MyMainClass -XX:+UseZGC
or java -jar myjar.jar -XX:+UseZGC
doesn't.
In older Java versions, there was another GC named CMS (Concurrent Mark and Sweep) that was enabled using -XX:+UseConcMarkSweepGC
. However, this GC was deprecated in JDK 9 and removed in JDK 14.Garbage collection can be customized using various other JVM arguments as well. Some of these are generally applicable while others are specific to a GC.
For instance, the maximum heap size can be configured with
-Xmx
(e.g. -Xmx1G
for 1GB) independently of the garbage collector.📖 Sample answer from dan1st
cli jvm flags.
-XX:+UseSerialGC
-XX:+UseParallelGC
-XX:+UseG1GC
1. enables a sequential garbage collector that runs on a single thread
2. activates a parallel garbage collector with multiple threads
3. enables the Garbage-first (G1) garbage collector, designed to minimize pauses
java -XX:+UseParallelGC -jar test.jar
also u can set heap size:
-Xms
= start size (512m, 1g)
-Xmx
= max size
default gc based on:
hardware | heap size ....
can be determined with flag -XX:+PrintCommandLineFlags
Submission from itskekoff
using -XX option
Like
-XX : +UseG1GC which means to use Garbage first garbage collector
Submission from gnani0026
Setting the garbage collector for a Java application is done through JVM command-line options when starting your program. JVM provides several garbage collection algorithms, each optimized for different use cases and performance requirements.
First and foremost, we need to understand the garbage collection process that is typically followed by the JVM, it includes:
- Marking: Identifying all reachable objects from GC Roots.
- Sweeping: Removing unreachable objects to claim memory.
- Compacting: Reorganizing remaining objects to reduce fragmentation.
Next, let's see and compare serveral garbage collector implementations, their characteristics and other collector parameters.
G1 Garbage Collector
Garbage First (G1) collector is designed for applications with large heaps and focuses on low latency. It divides the heap into regions and prioritizes collecting regions with the most garbage first.
To Enable G1:
java -XX:+UseG1GC -jar yourApp.jar
Z Garbage Collector
ZGC is a scalable and low-latency collector introduced in Java 11 that keeps pause times under 1ms (ZGC performs all expensive work concurrently, without stopping the execution of application threads for more than a millisecond) [1].
To enable ZGC, Use the following JVM Flags:
Java 15+: java -XX:+UseZGC -jar yourApp.jar
Java 11-14: java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar yourApp.jar
Serial and Parallel Collectors
Serial and Parallel are traditional generrational garbage collectors that divide the heap into young and old generations. All application threads are pausing during garbage collection operations when using serial and parallel collectors.
Serial Collector performs all garbage collection work on single thread, ideal for systems with single processor.
Parallel Collector utilizes multiple threads, resulting in a higher throughput.
Serial and Parallel Collectors although historically relevant are not much used as JVMs typically default to G1 GC, which attempts to balance throughput and latency.
Parallel GC JVM Flags: java -XX:+UseParallelGC -jar yourApp.jar
Serial GC JVM Flags: java -XX:+UseSerialGC -jar yourApp.jar
The rule of thumb for setting the garbage collector is as follows:
Sources:
[1] https://docs.oracle.com/en/java/javase/21/gctuning/z-garbage-collector.html#GUID-8637B158-4F35-4E2D-8E7B-9DAEF15BB3CD
Oracle Help Center
HotSpot Virtual Machine Garbage Collection Tuning Guide
Summary and Practical Considerations
- Default Behavior: If you don't specify a garbage collector, the JVM will choose one based on your system's characteristics. Modern JVMs often default to G1 or Parallel collectors depending on available system resource.
- Test different collectors: GC Behaviour varies between applications, it's recommended to test different collectors with your specific workload. You need to monitor metrics like pause time, throughput and memory usage to determine the best fit. (Metrics logging JVM Flag below.)
- G1 GC:
-XX:+UseG1GC
- ZGC: -XX:+UseZGC
- Parallel GC: -XX:+UseParallelGC
- Serial GC: -XX:+UseSerialGC
- Additional Tuning Parameters:
- Garbage Collection Performance Logging: -Xlog:gc*:file=gc.log
⭐ Submission from daysling