Xloggc实践(JVM1.8及之前)
Java服务器调优免不了要对gc日志进行分析,我一般是上传gc日志文件到GCEasy进行处理的,上传的文件有大小限制。另外默认的gc日志打印还会存在重启后丢失的问题。综上,我们希望gc日志文件在不能丢失(但允许超过一定时间或大小被清理掉)的情况下控制gc日志的大小或者按时间切割,即像Java日志框架那样的效果。Java9对jvm的日志系统进行了比较大的升级,可以比较好的实现这些需求,但大部分服务端的Java软件还只支持Jdk8,本文记录作者自己的相关配置。
分析
首先推荐看两篇gceasy的博客文章,网上对UseGCLogFileRotation的相关讨论很多都来自于这里:
https://blog.gceasy.io/2016/11/15/rotating-gc-log-files/
https://blog.gceasy.io/2019/01/29/try-to-avoid-xxusegclogfilerotation/
简单来说,UseGCLogFileRotation 可以控制gc日志文件大小,且按日期分片切割
缺点是:
- 记录丢失
个人认为不是问题,超过指定文件数量及大小的日志被丢弃是预期操作。 - 循环打印
若限制日志文件数共5个,分别为0、1、2、3、4,在文件4达到文件最大值后系统将从1开始覆写,最终的结果就是顺序错乱,不能直接使用(需要人为地修改文件名以修正顺序) - 重启后从编号0开始写入,而非上次的写入位置。结合第2点你就会发现你的日志顺序已经完全不可信了。
应对方法
- 直接使用-Xloggc:gc-%t.log(
推荐
)
简单粗暴,缺点是文件依然太大,需要用自己切割 - 结合-Xloggc:gc-%t.log使用
使用 -Xloggc:gc-%t.log可以解决问题3,但仍存在循环打印。- 设置较大的文件数量和大小限制,尽量使其不产生循环打印
上面文章讨论区的一个小伙伴提出的,其实也是个办法
以下是我的日志文件输出测试,不同一个批次的文件数量限制可能不同,用蓝框隔离。 - 手动调整顺序(其实也不麻烦)。
- 设置较大的文件数量和大小限制,尽量使其不产生循环打印
- 如果是业务系统的话直接用高版本的jdk吧,不用看这篇文章了
示例
(使用两个gc日志文件,每个文件最大为1k):
每一个批次都有一个current后缀的日志文件标识当前写入,同一批次的日志文件用从0开始的序号后缀隔开,通常current应该在序号最大的位置,如果不是则说明存在循环打印的情况。
1 |
|
Xloggc实践(JVM1.8及之前)
https://linshenkx.github.io/Xloggc/