1. Overview
Garbage collection is a marvel of the Java programming language providing us with automatic memory management. Garbage collection hides the details of having to manually allocate and deallocate memory. While this mechanism is fantastic, sometimes it doesn't work the way we want. In this tutorial, we'll explore Java's logging options for garbage collection statistics and discover how to redirect these statistics to a file.
2. GC Logging Flags in Java 8 and Earlier
First, let's explore the JVM flags relating to GC logging in Java versions prior to Java 9.
2.1. -XX:+PrintGC
The -XX:+PrintGC flag is an alias for -verbose:gc and turns on basic GC logging. In this mode, a single line is printed for every young-generation and every full-generation collection. Let's now turn our attention to providing detailed GC information.
2.2. -XX:+PrintGCDetails
Similarly, we have the flag -XX:+PrintGCDetails used to activate detailed GC logging instead of -XX:+PrintGC.
Note that the output from -XX:+PrintGCDetails changes depending on the GC algorithm in use.
Next, we'll look at annotating our logs with date and time information.
2.3. -XX:+PrintGCDateStamps and -XX:+PrintGCTimeStamps
We can add dates and timing information to our GC logs by utilizing the flags -XX:+PrintGCDateStamps and -XX:+PrintGCTimeStamps, respectively.
First, -XX:+PrintGCDateStamps adds the date and time of the log entry to the beginning of each line.
Second, -XX:PrintGCTimeStamps adds a timestamp to every line of the log detailing the time passed (in seconds) since the JVM was started.
2.4. -Xloggc
Finally, we come to redirecting the GC log to a file. This flag takes an optional filename as an argument using the syntax -Xloggc:file and without the presence of a file name the GC log is written to standard out.
Additionally, this flag also sets the -XX:PrintGC and -XX:PrintGCTimestamps flags for us. Let's look at some examples:
If we want to write the GC log to standard output, we can run:
java -cp $CLASSPATH -Xloggc mypackage.MainClass
Or to write the GC log to a file, we would run:
java -cp $CLASSPATH -Xloggc:/tmp/gc.log mypackage.MainClass
3. GC Logging Flags in Java 9 and Later
In Java 9+, -XX:PrintGC, the alias for -verbose:gc, has been deprecated in favor of the unified logging option, -Xlog. All other GC flags mentioned above are still valid in Java 9+. This new logging option allows us to specify which messages should be shown, set the log level, and redirect the output.
We can run the below command to see all the available options for log levels, log decorators, and tag sets:
java -Xlog:logging=debug -version
For example, if we wanted to log all GC messages to a file, we would run:
java -cp $CLASSPATH -Xlog:gc*=debug:file=/tmp/gc.log mypackage.MainClass
Additionally, this new unified logging flag is repeatable, so you can, for example, log all GC messages to both standard out and a file:
java -cp $CLASSPATH -Xlog:gc*=debug:stdout -Xlog:gc*=debug:file=/tmp/gc.log mypackage.MainClass
4. Conclusion
In this article, we've shown how to log garbage collection output in both Java 8 and Java 9+ including how to redirect that output to a file.