许用户深入了解数据。 JFR 和 JMC 可用于诊断运行时问题,例如内存泄漏、GC 开销、热点方法、线程瓶颈和阻塞 I/O。JMC可以作为现有JVM监控工具的一个补充,做到维度更多,监控更加实时(秒级),能从多个视角监控当前JVM进程的性能,更加更快速的定位并解决问题。
3.3 统一 JVM 日志(JEP158)
在以往的低版本中很难知道导致JVM性能问题和导致JVM崩溃的根本原因。不同的JVM对日志的使用是不同的机制和规则,这就使得JVM难以进行调试。
解决这个问题最佳的方法:对所有的JVM组件引入一个统一的日志框架,这些JVM组件支持细粒度的和易配置的JVM日志。 JDK8以前常用的打印GC日志方式:
-Xloggc:/export/Logs/gc.log //输出GC日志到指定文件
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
3.3.1 目标:
-
所有日志记录的通用命令行选项。
-
通过tag对日志进行分类,例如:compiler, gc, classload, metaspace, svc, jfr等。一条日志可能会含有多个 tag
-
日志包含多个日志级别:error, warning, info, debug, trace, develop。
-
可以将日志重定向到控制台或者文件。
-
error, warning级别的日志重定向到标准错误stderr.
-
可以根据日志大小或者文件数对日志文件进行滚动。
-
一次只打印一行日志,日志之间无交叉。
-
日志包含装饰器,默认的装饰器包括:uptime, level, tags,且装饰可配置。
3.3.2 如何使用
-Xlog[:option]
option := [][:[][:[][:]]]
'help'
'disable'
what := [,...]
selector := [*][=]
tag-set := [+...]
'all'
tag := name of tag
level := trace
debug
info
warning
error
output := 'stderr'
'stdout'
[file=]
decorators := [,...]
'none'
decorator := time
uptime
timemillis
uptimemillis
timenanos
uptimenanos
pid
tid
level
tags
output-options := [,...]
output-option := filecount=
filesize=
parameter=value
-
可以通过配置-Xlog:help参数,获取常用的JVM日志配置方式。
-
可以通过-Xlog:disable参数关闭JVM日志。
-
默认的JVM日志配置如下:
-Xlog:all=warning:stderr:uptime,level,tags
- 默认配置
- 'all' 即是包含所有tag
- 默认日志输出级别warning,位置stderr
- 包含uptime,level,tags三个装饰
-
可以参考使用如下配置:
JDK9之前参数-XX:+PrintGCDetails可参考:
-Xlog:safepoint,classhisto*=trace,age*,gc*=info:file=/export/Logs/gc-%t.log:time,tid,level,tags:filecount=5,filesize=50MB
- safepoint表示打印用户线程并发及暂停执行时间
- classhisto表示full gc时打印堆快照信息
- age*,gc* 表示打印包括gc及其细分过程日志,日志级别info,文件:/export/Logs/gc.log。
- 日志格式包含装饰符:time,tids,level,tags
- default output of all messages at level 'warning' to 'stderr'
will still be in effect
- 保存日志个数5个,每个日志50M大小
查看GC前后堆、方法区可用容量变化,在JDK9之前,可以使用-XX::+PrintGeapAtGC,现在可参考:
-Xlog:gc+heap=debug:file=/export/Logs/gc.log:time,tids,level,tags:filecount=5,filesize=1M
- 打印包括gc及其细分过程日志,日志级别info,文件:/export/Logs/gc.log。
- 日志格式包含装饰符:time,tids,level,tags
- default output of all messages at level 'warning' to 'stderr'
will still be in effect
- 保存日志个数5个,每个日志1M大小
JDK9之前的GC日志:
2014-12-10T11:13:09.597+0800: 66955.317: [GC concurrent-root-region-scan-start]
2014-12-10T11:13:09.597+0800: 66955.318: Total time for which application threads were stopped: 0.0655753 seconds
2014-12-10T11:13:09.610+0800: 66955.330: Application time: 0.0127071 seconds
2014-12-10T11:13:09.614+0800: 66955.335: Total time for which application threads were stopped: 0.0043882 seconds
2014-12-10T11:13:09.625+0800: 66955.346: [GC concurrent-root-region-scan-end, 0.0281351 secs]
2014-12-10T11:13:09.625+0800: 66955.346: [GC concurrent-mark-start]
2014-12-10T11:13:09.645+0800: 66955.365: Application time: 0.0306801 seconds
2014-12-10T11:13:09.651+0800: 66955.371: Total time for which application threads were stopped: 0.0061326 seconds
2014-12-10T11:13:10.212+0800: 66955.933: [GC concurrent-mark-end, 0.5871129 secs]
2014-12-10T11:13:10.212+0800: 66955.933: Application time: 0.5613792 seconds
2014-12-10T11:13:10.215+0800: 66955.935: [GC remark 66955.936: [GC ref-proc, 0.0235275 secs], 0.0320865 secs]
JDK9统一日志框架输出的日志格式 :
[2021-02-09T21:12:50.870+0800][258][i