如何监控GC
gc监控是GC调优的必要前提,只有监控数据,才能知道该不该GC调优?如何调优?调优是不是有效果?
有很多种方法可以监控GC,其差别只是展现的形式而已,所以不用特意的去学习所有监控gc的方法。
jstat
jstat 是HotSpot JVM提供的一个监控工具,jstat 不仅提供GC操作的信息,还提供类装载操作的信息以及运行时编译器操作的信息。
jstat 被放置在 $JDK_HOME/bin。因此只要java 和 javac能执行,jstat 同样可以执行。
你可以在命令行环境下执行如下语句。
jps 获取进程id
jps
jstat -gc 28352 1000
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
122048.0 124224.0 0.0 1945.4 1452288.0 537235.5 490368.0 163970.8 - - - - 33 1.843 2 0.697 2.541
122048.0 124224.0 0.0 1945.4 1452288.0 537235.5 490368.0 163970.8 - - - - 33 1.843 2 0.697 2.541
122048.0 124224.0 0.0 1945.4 1452288.0 537235.5 490368.0 163970.8 - - - - 33 1.843 2 0.697 2.541
122048.0 124224.0 0.0 1945.4 1452288.0 537235.5 490368.0 163970.8 - - - - 33 1.843 2 0.697 2.541
122048.0 124224.0 0.0 1945.4 1452288.0 537235.5 490368.0 163970.8 - - - - 33 1.843 2 0.697 2.541
想要得到GC性能相关的数据需要持续不断地监控,因此在执行jstat时,要规则地输出GC监控的信息。
执行jstat –gc 1000 (或 1s)会每隔一秒展示GC监控数据。jstat –gc 1000 10会每隔1秒展现一次,且一共10次。
可以使用 jstat -options
来查看其他的选项,不同的jdk版本可能会有所差异。
选项 | 描述 |
---|---|
gc | 显示了每个堆区域的当前大小及其当前使用情况(Ede、survivor、old 等)、执行的 GC 总数以及 GC 操作的累积时间 |
gccapactiy | 显示了每个堆区域的最小大小 (ms) 和最大大小 (mx)、当前大小以及每个区域执行的 GC 次数。(不显示 GC 操作的当前使用情况和累积时间 |
gccause | 它显示了 -gcutil 提供的信息 最后一次GC 的原因和当前 GC 的原因。 |
gcnew | 显示年轻代空间的GC性能数据 |
gcnewcapacity | 显示年轻代空间大小的统计数据 |
gcold | 输出老年代空间的GC性能数据 |
gcoldcapacity | 输出老年代空间的大小统计数据 |
gcpermcapacity | 输出永久代空间的大小统计数据 |
gcutil | 输出每个堆区域使用占比,以及gc执行的总数和GC操作的累计时间 |
使用最多的命令,gcutil,gc,gccapacity
- gcutil用于检查堆区域的使用情况、执行的 GC 次数以及 GC 操作的总累积时间
- gccapacity选项和其他选项可用于检查分配的实际大小。
- gc 用于实时查看当前gc情况
输出列的信息
总结:jstat的好处,只要有控制台的地方就可以使用。
当使用–gcutil 会输出如下信息。在GC优化的时候,你需要特别注意YGC, YGCT, FGC, FGCT 和GCT。
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 66.44 54.12 10.58 86.63 217 0.928 2 0.067 0.995
0.00 66.44 54.12 10.58 86.63 217 0.928 2 0.067 0.995
0.00 66.44 54.12 10.58 86.63 217 0.928 2 0.067 0.995
在这个例子中,YGC(年轻代gc的总次数) 是217而YGCT(年轻代gc总共的时间) 是0.928,这样在简单的计算数据平均数后(0.928/217=0.004秒),你可以知道每次新生代的GC大概需要4ms(0.004秒),而full GC的平均时间为33ms。
但是这并不能说明问题,平均数据无法分析确定每次gc花费的时间,比如full gc总耗时70ms,一共gc两次,其中一次是10ms,而另外一次可能是60ms,所以为了更准确的确定gc问题,可以使用 -verbosegc。
-verbosegc
-verbosegc 是在启动一个Java应用时可以指定的JVM参数,jstat可以在没有指定任何jvm参数下使用。
下面是-verbosegc 的可用参数
- -XX:+PrintGCDetails
- -XX:+PrintGCTimeStamps
- -XX:+PrintHeapAtGC
- -XX:+PrintGCDateStamps (from JDK 6 update 4)
jdk1.6示例
java -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:./gc.log -jar test.jar
YoungGC日志解释如下 :
FullGC日志解释如下
springboot actuator报点 + prometheus收集 + grafana图形展示
1.基于springboot的业务报点gradle配置:
compile 'org.springframework.boot:spring-boot-starter-actuator'
compile 'io.micrometer:micrometer-registry-prometheus'
2.配置yml
management:
endpoints:
web:
exposure:
include: health,prometheus
默认报点的url:
http://ip:port/actuator/prometheus
3.安装promethues
4.安装grafana,导入Spring Boot 2.1 Statistics模板
内存泄露-年轻代的eden区的特征:
内存泄露-老年代的特征:
内存泄露-年轻代的survivor区的特征:
内存泄露-gc Stop The World 曲线图:
总结
一般使用jstat来监控gc,如果感觉gc有问题,可以使用verbosegc参数。如果你使用springboot,可以使用springboot actuator报点 + prometheus收集 + grafana图形展示 方案。