Automatic Garbage Collection is one of the powerful features of the Java programming language. Garbage Collection performance is primarily studied from Garbage Collection Log. Garbage Collection Log is a gold mine to improve our application performance. It contains a wealth of information such as:

a. Information about every GC event that ran in the application 

b. At what time did GC event run

c. How long did the GC event take to complete the event

d. How many objects were reclaimed from each JVM Memory region

e. Reason why the GC event was triggered

:

This information is not only helpful to optimize JVM’s performance but also provide deeper insights to debug memory problems. In this post let’s discuss how to read and analyze GC logs.

How to enable GC Log?

You can generate GC log file, by passing following JVM arguments to your application:

Until Java 8:

If your application is running on Java 8 or below version, pass below JVM arguments:

-XX:+PrintGCDetails -Xloggc:<gc-log-file-path>

Example:

-XX:+PrintGCDetails -Xloggc:/opt/tmp/myapp-gc.log

From Java 9:

If your application is running on Java 9 or above version, pass below JVM arguments:

-Xlog:gc*:file=<gc-log-file-path>

Example:

-Xlog:gc*:file=/opt/tmp/myapp-gc.log

This will generate the GC log in the specified file path. 

If time permits, we recommend you to read GC logging best practices post, to capture GC log events in a pristine format.

GCeasy Tool to Analyze GC Log

In each GC log, thousands of GC events information are present. Trying to read and digest GC events information in a GC log is a time consuming, tedious and complex task. Thus, you can use GC log analysis tools like GCeasy, which can analyze all formats of GC logs and give recommendations and JVM settings to optimize your application’s GC performance.

GC Log Analysis: Here is the sample GC log report generated by the GCeasy tool by analyzing a GC log file. 

GC Metrics and Graphs

GCeasy tool’s report provides several graphs and fine-grained metrics to study the GC behavior in your application. Below are some of the excerpts from the GC log analysis report:

Fig: GC Key Performance Indicators by GCeasy

There is a famous saying: “You can’t optimize, what you can’t measure”. Thus, when it comes to GC tuning you need to be aware of the Key Performance Indicators that you are trying to tune. The above figure shows the GC KPIs that are sourced from the GC log file.

Fig: Heap Usage Graph generated by GCeasy

In the above graph you can notice the Heap usage trend after every GC event. You can notice that after every GC event, memory size drops. You can zoom-in in the real GCeasy report to see how memory usage is dropping.

Fig: GC Pause Duration Time

The above ‘GC Duration Time’ graph shows the Pause time of each GC event. You can notice that the Full GC events (i.e. red triangle) take more time than Young GC events (i.e. blue squares). You can see that most of the Young GC events are completed in under 1 second, whereas Full GC events are taking around 40 seconds. This is because Full GC events run all the 3 regions of the JVM Memory (i.e., Young Gen, Old Gen and Metaspace), whereas Young GC runs only on 1 region (i.e., Young Gen).

Fig: Recommendations given by GCeasy to optimize GC performance

Besides the metrics and visuals, the tool also gives recommendations and JVM settings to optimize the GC performance as shown in the above figure.

Tune GC Performance

If you are looking to tune GC performance, I would like to share few pointers:

  1. 9 Tips to Reduce GC Pause Time: This post gives general 9 tips to reduce any GC algorithm’s pause time
  2. How to improve GC Throughput: This post talks about how you can go about improving your GC throughput. 
  3. What is the right GC algorithm for my application: This post talks about how you can go about approaching right GC algorithm for your application. 

GC Algorithms and it’s GC Log Format

As of 2025, there are 7 GC algorithms in OpenJDK. Log formats are not standardized, each GC algorithm has its own GC log format. In the table below, I have given hyperlinks to blog posts that talk about each GC algorithm’s log formats. These posts will give a detailed view of each GC algorithm’s log structure.

GC AlgorithmDescription
Serial GCA simple, stop-the-world, single-threaded garbage collector designed for small applications with low memory footprints.
Parallel GCA throughput-focused garbage collector that uses multiple threads for minor and full GC operations to improve performance.
CMS GCThe Concurrent Mark-Sweep collector reduces pause times by performing most of its work concurrently but is deprecated and replaced by modern collectors.
G1 GCThe Garbage-First collector optimizes pause times by incrementally collecting garbage in regions rather than entire heap generations.
Shenandoah GCA low-pause-time collector that performs concurrent compaction, reducing stop-the-world events significantly.
ZGCAn ultra-low-latency collector designed to handle large heaps (up to terabytes) while keeping pause times under a few milliseconds.
Epsilon GCA no-op garbage collector that does no memory reclamation, useful for testing and benchmarking applications without GC overhead.

Conclusion

Hopefully in this post, you learnt how to enable GC log, how to interpret GC events and how to analyze them. If you would like to learn more about GC Tuning, please check out my online ‘JVM Performance Engineering & Troubleshooting Master Class’.