JDK8からあるちょっと嬉しいGCログオプション
JDK8およびJDK8u20では、GCログに関連する2つの便利な機能が追加されている。いずれの機能も2014/8現在最新のJDK7 update 67 には含まれていないが、JDK7u80にてバックポートされる予定。
GCログにpidと日付を含める (JDK8より)
JAVA_OPTS="$JAVA_OPTS -Xloggc:/var/log/wildfly/gc_%p_%t.log" => 実際のファイル名例 : gc_pid31455_2014-08-31_14-20-16.log.0
GCログのフォーマットに%pを入れるとpid-Xloggc:gc.log.`date +%Y%m%d%H%M%S`
のようにOSコマンドによってファイル名に日付を付与していたが、この機能の追加によりOSコマンドへの依存がなくなるので便利。
jcmd GC.rotate_logによるローテーション (JDK8u20より)
JDK8u20よりjcmdにGCログをローテーションさせるコマンドが追加されている。
jcmd <pid> GC.rotate_log
以前よりGCログにはサイズローテーション機能が付与されていたが、Javaの場合ログのリロード機能がないため、logrotate.dなどによる日付ローテーションが困難であった。GC.rotate_logの導入により、以下の起動オプションと組み合わせると日付契機のログローテーションが実現できる。
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=0
UseGCLogFileRotationおよびNumberOfGCLogFilesが設定されていない状態でjcmd
を実行すると、GCログローテーションが有効となっていないことを示すエラー(Target VM does not support GC log file rotation.)となる。また、GCLogFilzeSize=0を設定し、ファイルサイズ契機のローテーションを止めている。
NumberOfGCLogFilesの指定がGC.rotate_logの実行に必須であるため、 ログの世代数管理をlogrotate.dに任せるのは難しい。またファイルのコピーや世代数を超えたファイルの削除はJVMが行ってくれるため、logrotate.dを使わずにまずはお試しとして直接cron.dailyに入れてみた。
# touch /etc/cron.d/cron.daily/gclog_rotate # vim /etc/cron.d/cron.daily/gclog_rotate #!/bin/sh sudo -u wildfly /usr/java/jdk1.8.0_20/bin/jcmd `cat /var/run/wildfly/wildfly.pid` GC.rotate_log
/var/run/wildfly/wildfly.pidより起動中のWildFlyのプロセスIDを確認している。WildFlyでなくても、/etc/rc.d/init.dに登録している場合は/var/run配下に現状のプロセスIDを示すファイルが出力されると思う。