Rolling garbage collector logs in java

2019-01-16 23:07发布

问题:

Is it possible to do a rolling of garbage collector logs in Sun JVM?

Currently I generate logs using:

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -verbose:gc -Xloggc:gc.log 

But I have to manually rotate them using fifo queues and rotatelogs to create a new log for each day. I hope that there is a better solution for this.

Maybe there is a way to access this log entries from inside java so I could redirect them to log4j?

Edit: the solution with fifo queue is not good enough because if the process that reads from this queue (e.g. rotatelogs) reads to slow it will slow down the entire jvm (apparently Sun/Oracle does gc logging synchronously)

回答1:

Built-in support for GC log rotation has been added to the HotSpot JVM. It is described in the RFE 6941923 and is available in:

  • Java 6 Update 34
  • Java 7 Update 2 (but there is no reference to it in these release notes)

There are three new JVM flags that can be used to enable and configure it:

  • -XX:+UseGCLogFileRotation
    must be used with -Xloggc:<filename>;
  • -XX:NumberOfGCLogFiles=<number of files>
    must be >=1, default is one;
  • -XX:GCLogFileSize=<number>M (or K)
    default will be set to 512K.


回答2:

If you can't upgrade your java version to use the new flags for rotating the gc log then you could specify a different gc file each time the application starts:

JAVA_OPTS="-Xms1024m -Xmx1024m -XX:MaxPermSize=256m -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/path/to/log/dir/gc.log-"`date +%Y-%m-%d-%H-%M`

When the setenv is referenced, usually at startup or shutdown, it will reference a different log file. In unix this can be used as a method for 'rotating' the log.



回答3:

Have you tried this new options?

I tried jdk7u7, jdk7u6 and jdk6u35 like this:

java -Xloggc:gc.log -XX:+PrintGCDetails -XX:+UseGCLogRotation -XX:NumberOfGClogFiles=3 -XX:GCLogFileSize=10M

but with every version I'm seeing this error:

Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

Bugfix #6941923 for 7u2 is referenced here: http://www.oracle.com/technetwork/java/javase/2col/7u2bugfixes-1394661.html



回答4:

An interesting approach would be to redirect gc.log to a named pipe -Xloggc:/my/named/pipe How to write GC log to named pipe

then read that pipe form the application itself: How to open a Windows named pipe from Java?

and log to an arbitrary (e.g. async rolling) logback logger from the code.

Tried that on a Windows machine. Unfortunately, it is trickier to setup on Windows than on Linux.

On Windows it works basically with help of an additional Powershell script (can be a dedicated application as well). This sample project also contains a demo application that can be used right away to test the GC logs redirection to Logback via SLF4J.



回答5:

I ended up solving this problem by spawning a new thread in my application and sending jcmd log-rotate command periodically (based on a cron expression).

This is an unconventional approach as you will be using Oracle's Attach API, although the approach served our use case of rotating GC logs hourly.