简介
我们平时说的jvm调优,其实大多数时间都在调优jvm的gc,因为gc是jvm最核心的一部分。查看gc情况有以下途径:
其中jstat和jmx都无法得到详细信息,仅能获取到相关的ygc和fgc的次数。并且jstat工具因为比较老的缘故,该工具的输出结果和真实情况不太匹配。
jstat的典型输出结果
S0 S1 E O M CCS YGC YGCT FGC FGCT CGC CGCT GCT
0.00 32.44 9.59 0.05 95.95 89.82 1 0.003 0 0.000 - - 0.003
0.00 32.44 9.59 0.05 95.95 89.82 1 0.003 0 0.000 - - 0.003
0.00 32.44 9.59 0.05 95.95 89.82 1 0.003 0 0.000 - - 0.003
0.00 32.44 9.59 0.05 95.95 89.82 1 0.003 0 0.000 - - 0.003
其中ygc代表"新生代gc次数",fgc代表"fullgc次数".相信看到这里,对gc有深层次了解的同学就感觉到不对劲了。
gc可以分为:新生代gc/young gc
,老年代gc / old gc
,兜底的fullgc
,按照jstat的数据格式,就无法区分出老年代gc
和fullgc
,所以jstat其实笼统地用fgc
同时表达了老年代gc
和fullgc
.
笔者注:java因为开发年代久远,所以设计上其实有很多小缺点,这里提一个同样有问题的设计:Boolean 类,提供了public得构造器,而其实它根本不需要有多个实例。所有常见的Boolean.TRUE 都是一个概念。
只有gc日志可以获取到完整的gc信息:什么时间发生了gc,gc的类型是什么,gc前后堆各个空间的大小变化,gc持续了多长时间,触发gc的原因。划重点:GC日志是唯一精确诊断gc问题的手段。
如何生成gc日志
在jvm启动命令行里面添加-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/dev/shm/gc.log
即可。gc日志会被输出到/dev/shm/gc.log
文件里
如果之前没开始,又想查看gc日志怎么办?
通过jinfo -flag +PrintGCDetails $pid
可以动态开启jvm的gc日志输出,日志会被输出到console中。
如何分析日志?
gc日志是非结构化日志,在不同gc算法、不同版本之间的格式都不一样,所以这里我们借助现成的gc可视化工具来分析gc日志,moyucoding.com 就是一个gc日志分析的工具,你同样可以使用gceasy来完成分析。
moyucoding 得gc日志分析非常简单,选择gc日志文件,上传即可。
gc日志分析结果,从截图可以看到,最大涨停时间为0.134s,整体吞吐率为98%,总共有1610次GC,GC类型有TENURING_DISTRIBUTION, G1_YOUNG_PAUSE, G1_YOUNG_INITIAL_MARK, G1_CONCURRENT, G1_REMARK, G1_CLEANUP, G1_MIXED_PAUSE
moyucoding工具不仅能数字化gc日志,还能根据gc日志的表现,给出基于机器学习的诊断意见。