java中的滚动垃圾收集器日志
是否可以在Sun JVM中滚动垃圾收集器日志 目前,我使用以下方法生成日志:java中的滚动垃圾收集器日志,java,logging,garbage-collection,Java,Logging,Garbage Collection,是否可以在Sun JVM中滚动垃圾收集器日志 目前,我使用以下方法生成日志: -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -verbose:gc -Xloggc:gc.log 但我必须使用fifo队列和rotatelogs手动轮换它们,为每天创建一个新日志。我希望有更好的解决办法 也许有一种方法可以从java内部访问这些日志条目,这样我就可以将它们重定向到log4j 编辑:使用fifo队列的解决方案不够好
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -verbose:gc -Xloggc:gc.log
但我必须使用fifo队列和rotatelogs手动轮换它们,为每天创建一个新日志。我希望有更好的解决办法
也许有一种方法可以从java内部访问这些日志条目,这样我就可以将它们重定向到log4j
编辑:使用fifo队列的解决方案不够好,因为如果从该队列读取的进程(例如rotatelogs)读取速度减慢,则会减慢整个jvm(显然Sun/Oracle同步执行gc日志记录)内置的gc日志旋转支持已添加到热点jvm中。 有关详细信息,请参见,并可从以下网址获得:
- (但本发行说明中未提及)
-XX:+UseGCLogFileRotation
必须与
一起使用李>-Xloggc:
-XX:NumberOfGCLogFiles=
必须>=1,默认为1李>-XX:GCLogFileSize=M(或K)
默认值将设置为512K
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:如果您无法升级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中,这可以用作“旋转”日志的方法。一个有趣的方法是将gc.log重定向到命名管道
-Xloggc:/my/named/pipe
然后阅读应用程序本身的管道:
并从代码中登录到任意(例如异步滚动)回写日志记录器
在Windows机器上尝试过。不幸的是,在Windows上设置要比在Linux上设置复杂得多
在Windows上,它基本上是在其他应用程序的帮助下工作的(也可以是专用应用程序)。
这还包含一个演示应用程序,可以立即使用它来测试通过SLF4J重定向到Logback的GC日志。我通过在应用程序中生成一个新线程并定期发送log rotate命令(基于cron表达式)来解决这个问题
这是一种非传统的方法,因为您将使用Oracle,尽管这种方法适用于我们每小时旋转GC日志的用例。使用-XX:+UseGCLogFileRotation会导致solaris和JDK版本1.7.0_80-1.7.0_97和1.8.0_20-1.8.0_77出现一些严重的长期安全点问题。您的解决方案对我来说非常好;你不喜欢它的什么地方?你有托管:这种循环发生在Java调用(配置日志记录)附近,而不是在应用程序代码中(应用程序代码应该不会被日志记录所影响)。我的直觉也会说不,这是不可能的,或者如果可能的话,它将通过私有,您可能不想将其强制应用到应用程序中的受限API。-XX:+PrintGCDateStamps未应用于java5?-XX:NumberOfGClogFiles应该有一个大写字母L(-XX:NumberOfGClogFiles)。遗憾的是,这不是每天都有,我没有看到大小滚动的点,我通常希望看到给定日期的日志,不是123MB:)大小滚动的要点是日志文件的总大小受到限制(限制为NumberOfGCLogFiles*GCLogFileSize),这避免了设备上没有剩余空间的错误,并克服了查找给定日期日志的不便。@krzyk一种解决方法可能是将日志记录到带有日期戳的命名文件中,然后每天重新启动日志记录机制。@ThorbjørnRavnAndersen如何“每天重新启动日志记录机制”如果不重新启动JVM?您的标志是错误的-它是“-XX:+UseGCLogFileRotation”(您缺少标志中的“文件”)并且“-XX:NumberOfGClogFiles”中缺少大写字母“L”(正如我最初的回答中所述)这不是Blazej的错,错误在他引用的错误文档中()。更好的方法是将详细输出附加到文件,并使用logrotate或类似工具旋转此文件。您可以获得更长的日志,而不会被分解成一堆不同的文件。@Pathduck此答案适用于较旧的java版本。这意味着您不能附加到Xlogcc。我的实验还表明,不能让正在运行的java关闭并重新打开日志。您也不能让它搜索(EOF),java会记住Xloggc中的文件位置。不幸的是,并不是所有的系统都有logrotate。此解决方案专为那些不得不离开的管理员发布。以这种方式追加日期对于旋转catalina.out:-)将日期追加到名称中的问题是,在六个月后,服务器多次重新启动,最终会产生大量杂乱的日志,除非设置了logrotate来清理这些日志,否则它们只会停留在那里。一台或两台服务器没有问题,但数百台服务器可能有问题,也可能没有问题,这取决于您对凌乱日志目录的态度:)另请参见:我同意。因此:
find/opt/app/data/gc-type f-mtime+69-execrm-rf{}代码>据我所知,您必须让一个使用者监听命名管道,否则它最终将被阻塞。是的,这就是脚本项目。它还包含一个“阀门”,用于“没有任何东西接收到消息”的情况,以及一些描述该消息的注释。尽管它很有趣,但这意味着您的应用程序现在依赖于此外部组件才能正常运行。对我们来说,这很可能意味着我们不能在生产中使用它:-/该组件是并置的,并且与主JVM一起运行,可以编写脚本一起启动。您的代码还依赖于JVM进程,它在JVM进程中和某些操作系统进程上运行,通常还依赖于其他应用程序服务等