We sometimes encounter Java users who believe enabling garbage collection logging will have a significant impact on their performance metrics. Let’s examine the facts and myths.
About the Garbage CollectorThe Java garbage collector is a crucial part of the Java Virtual Machine (JVM) that affects your application’s performance and reliability. If you want to dive into the details of the different types of garbage collectors that are available in the Java runtime and how they work, check out this earlier blog post: “What Should I Know About Garbage Collection as a Java Developer.”
What Is GC Logging?Garbage collection (GC) logging is a feature of the JVM that provides information about the garbage collection process. Thanks to the generated log files, you can get insights into how the JVM manages memory dynamically at runtime by collecting and disposing of objects that the program no longer needs. This is very useful when you want to monitor the performance of a Java application, diagnose memory leaks and tune the JVM’s garbage collection configuration.
“Some of our customers chase every microsecond to improve the performance of their applications, but they still enable GC logging,” notes Daniel Witkowski, sales engineer at Azul. “Because it has little to no impact on application performance and allows debugging many different problems, it is vital for these companies to always be able to retrieve the GC logs after a problem has occurred.”
When garbage collection logging is enabled, every time the JVM performs a garbage collection, the following information is stored in a log file:
The log file is human-readable, and the content looks like this:
The stored information and format may vary depending on the JVM and the GC algorithm you use.
Enabling GC LoggingGC logging is enabled with the Java command line argument -Xlog
. This has been available since Java 9, thanks to JEP 158 “Unified JVM Logging”:
-Xlog:gc,safepoint:gc.log
to enable default logging of the important garbage collection events including all safepoint pauses.-Xlog:gc*,safepoint:gc.log
to enable more detailed logging, including all safepoint pauses and smaller garbage collector events and phases that are normally not logged. For OpenJDK, this is often needed; otherwise, some Java heap memory metrics are not recorded, and not all pauses are tracked. On Zing, it’s not needed, as all necessary data is already logged by default with just gc
. The tradeoff between gc
and gc*
is usually 10 times more log data amount, which will reduce the time interval your log covers.-Xlog:gc,safepoint
to write the log data to stdout
, which can be helpful in containers to avoid storing local log files.-Xlog:gc,safepoint:gc.log::filecount=10,filesize=100M
to change the default log rotation of 5 files of 20MB each to 10 files of 100MB each.-Xlog:gc,safepoint:gc.log::filecount=0
to disable log file rotation, useful for quick test runs or for processes that are restarted often. Note the double colon.You can even repeat the -Xlog
argument and use it to specify different outputs at the same time — for example, the following writes it to stdout
and to a local file:
$ java -Xlog:gc,safepoint -Xlog:gc,safepoint:/opt/log/gc.log -jar myApp.jar
There are more options available with the unified logging system, as you can see when you run the following command:
Impact of GC LoggingEnabling GC logging in a Java application generally has minimal performance impact, especially with modern JVMs. However, the exact impact may vary based on the JVM version, the GC algorithm used, the settings of GC logging and the I/O performance of the system where logs are written. These are a few facts you’ll need to take into consideration:
“The practical performance topic users should consider regarding GC logging is the amount of data in the filesystem,” says Holger, customer staff engineer at Azul. “A system halt due to a full filesystem would result in really bad performance. When using only -Xlog:gc:gc.log
for Zing or -Xlog:gc,safepoint:gc.log
for OpenJDK, you get all necessary performance-relevant metrics without wasting too much space. Especially on Zing, -XX:+PrintGCDetails, gc*
, or safepoint are not needed as they don’t add more graphs in GCLogAnalyzer.”
“A big part of the GC log tasks is saving the data to a log file. The type of I/O used to store these files can impact the logging performance, not directly the application itself,” explains Deepak Sreedhar, principal software engineer at Azul. “So, some of the problems that may occur are not related to the performance of the GC logging but to the speed of the I/O. If the logs can’t be saved fast enough in real time, OpenJDK has the option to use asynchronous unified logging with Xlog:async
.
When using Azul Zing, you only need to add -Xlog:gc:gc.log
to instruct Zing to store garbage collector log files. Extra arguments like gc*
or safepoint to increase the detail level are not needed, as Zing always logs safepoint pauses and even additional information not seen in OpenJDK GC logs by default, like just-in-time (JIT) compiler activity, CPU and memory usage, Linux page cache metrics, and a few more metrics often relevant for system performance analysis.
There are various tools available to analyze the content of GC log files:
jstat
command: This utility displays performance statistics and can be used to output garbage collector statistics.Although garbage collection logs can introduce minimal performance costs, the trade-off is usually worthwhile, as the logs are often invaluable when tuning garbage collection and diagnosing memory issues. Without GC logs enabled, you can lose insights into how the JVM manages memory dynamically at runtime. This information is very useful for monitoring the performance of a Java application, diagnosing memory leaks and tuning the JVM’s garbage collection configuration.
YOUTUBE.COM/THENEWSTACK
Tech moves fast, don't miss an episode. Subscribe to our YouTube channel to stream all our podcasts, interviews, demos, and more.
Group Created with Sketch.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4