是否可以在Sun JVM中滚动垃圾收集器日志?
目前我使用以下方式生成日志:
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -verbose:gc -Xloggc:gc.log
但是我必须使用fifo队列和rotatelogs手动旋转它们以创建每天的新日志。我希望有更好的解决方案。
也许有办法从java里面访问这些日志条目,所以我可以将它们重定向到log4j?
编辑:使用fifo队列的解决方案不够好,因为如果从这个队列中读取的进程(例如rotatelogs)读取速度变慢,则会减慢整个jvm(显然Sun / Oracle会同步执行gc日志记录)
答案 0 :(得分:82)
HotSpot JVM中添加了对GC日志轮换的内置支持。 它在RFE 6941923中有描述,可在以下位置找到:
有三个新的JVM标志可用于启用和配置它:
-XX:+UseGCLogFileRotation
-Xloggc:<filename>
; -XX:NumberOfGCLogFiles=<number of files>
-XX:GCLogFileSize=<number>M (or K)
答案 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出现一些严重的长期安全点问题