滚动垃圾收集器登录java

时间:2010-09-29 13:35:59

标签: java logging garbage-collection

是否可以在Sun JVM中滚动垃圾收集器日志?

目前我使用以下方式生成日志:

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

但是我必须使用fifo队列和rotatelogs手动旋转它们以创建每天的新日志。我希望有更好的解决方案。

也许有办法从java里面访问这些日志条目,所以我可以将它们重定向到log4j?

编辑:使用fifo队列的解决方案不够好,因为如果从这个队列中读取的进程(例如rotatelogs)读取速度变慢,则会减慢整个jvm(显然Sun / Oracle会同步执行gc日志记录)

6 个答案:

答案 0 :(得分:82)

HotSpot JVM中添加了对GC日志轮换的内置支持。 它在RFE 6941923中有描述,可在以下位置找到:

有三个新的JVM标志可用于启用和配置它:

  • -XX:+UseGCLogFileRotation
    必须与-Xloggc:<filename>;
  • 一起使用
  • -XX:NumberOfGCLogFiles=<number of files>
    必须为&gt; = 1,默认为1;
  • -XX:GCLogFileSize=<number>M (or K)
    默认设置为512K。

答案 1 :(得分:6)

如果无法升级java版本以使用新标志来旋转gc日志,那么每次应用程序启动时都可以指定不同的gc文件:

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`

当引用setenv时,通常在启动或关闭时,它将引用不同的日志文件。在unix中,这可以用作“旋转”日志的方法。

答案 2 :(得分:3)

你试过这个新选项吗?

我试过像这样的jdk7u7,jdk7u6和jdk6u35:

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

但是每个版本我都会看到这个错误:

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

此处引用了7u2的修正号#6941923:http://www.oracle.com/technetwork/java/javase/2col/7u2bugfixes-1394661.html

答案 3 :(得分:1)

一种有趣的方法是将gc.log重定向到命名管道 -Xloggc:/my/named/pipe How to write GC log to named pipe

然后从应用程序本身读取该管道: How to open a Windows named pipe from Java?

并从代码中记录任意(例如异步滚动)logback记录器。

在Windows机器上尝试过。不幸的是,在Windows上设置比在Linux上设置更棘手。

在Windows上,它基本上可以借助额外的Powershell script(也可以是专用应用程序)。 此sample project还包含一个演示应用程序,可以立即使用它来测试GC日志重定向到SLF4J的Logback。

答案 4 :(得分:0)

我最终通过在我的应用程序中生成一个新线程并定期发送jcmd log-rotate命令(基于cron表达式)解决了这个问题。

这是一种非传统的方法,因为您将使用Oracle Attach API,尽管该方法适用于我们每小时轮换GC日志的用例。

答案 5 :(得分:0)

使用-XX:+ UseGCLogFileRotation将导致solaris和JDK版本1.7.0_80-1.7.0_97和1.8.0_20-1.8.0_77出现一些严重的长期安全点问题