使用JCMD采集JFR

我在上一篇博客中简单介绍了JCMD的几个常见的用法,可以进行线程dump,内存转存,内存对象直方图分析等。可以说,JCMD集成了以前我们常用的jstack,jps,jmap等命令,就像瑞士军刀一样,all in one。除了这些功能,JCMD还能够采集JFR信息进行性能分析。

JFR: Java Fly Record

JFR全称java fly record,是Java平台性能分析和事件采集的框架,且是JDK自带的工具。JFR可以采集到low-level的性能信息,而且对Java程序的性能影响几乎可以忽略不计,主要是因为JFR是直接采集的JVM内部的信息。如果你要将JFR商用,那么你需要去买oracle的商业证书,当然开发环境可以免费使用。

解锁Java程序的商业特性

由于JFR是商用的,所以需要解锁Java程序的商业feature,通过如下的JVM参数:

java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder

在JDK 1.8u40之后版本,不需要在启动的时候通过flag来解锁了,可以动态的解锁。
首先用jcmd查看下商业feature是否已解锁:

➜  target git:(master) ✗ jcmd 12174 VM.check_commercial_features
12174:
Commercial Features are locked.

如果没有解锁,使用下面的命令解锁:

➜  target git:(master) ✗ jcmd 12174 VM.unlock_commercial_features
12174:
Commercial Features now unlocked.

这时候,就可以运行许JFR采集任务了。

采集JFR

采集JFR有两种方式:

  • 固定时长的采集
  • 持续不断的采集

对于固定时长的采集,JFR会采集固定时长的事件并转存到指定的文件。对于持续不断的采集,不会把采集的事件转存到文件,需要手动去转存。JFR会把采集到的事件存到一个全局缓存,当缓存满了,会丢弃缓存中老的事件。所以,当你手动转存时,只会转存缓存中可用的数据,

启用持续不断的缓存,在发现问题的时候可以很方便的转存采集到的事件。

在我们启动JFR采集任务时,可以指定一个配置文件,配置文件定义了采集哪些事件,以及阈值。

JDK默认自带了两个配置文件,

➜  Home ll jre/lib/jfr
total 80
-rw-rw-r--  1 root  wheel    20K  7 22  2017 default.jfc
-rw-rw-r--  1 root  wheel    20K  7 22  2017 profile.jfc

在运行"连续不断"的JFR采集任务时,使用默认配置default.jfc。默认配置的开销很低,适用于一直运行,这样不会影响Java程序的性能。

profile.jfc采集的事件力度更细。

采集固定时长的JFR

下面的命令启动了一个10分钟的JFR任务:

jcmd 12174 JFR.start name=10min.jfr settings=profile delay=3s duration=5m filename=/Users/jianyuan/Personal/10_min.jfr compress=true
12174:
Recording 2 scheduled to start in 3 s. The result will be written to:

/Users/jianyuan/Personal/10_min.jfr

可以使用JFR.check来查看当前有哪些JFR任务在执行:

➜ jcmd 12174 JFR.check
12174:
Recording: recording=2 name="10min.jfr" duration=5m filename="/Users/jianyuan/Personal/10_min.jfr" compress=true (running)                                

持续采集JFR

通过下面命令启动一个持续不断的JFR任务:

➜  jcmd 12174 JFR.start name=endless settings=profile delay=3s duration=0  compress=true
12174:
Recording 3 scheduled to start in 3 s. No limit (duration/maxsize/maxage) in use.

Use JFR.dump name=endless filename=FILEPATH to copy recording data to file.

之前提过,对于这种持续采集的任务,我们需要手动转存:

➜ jcmd 12174 JFR.dump recording=3 filename="/Users/jianyuan/Personal/dump_endless.jfr" compress=true
12174:
Dumped recording 3, 646.0 kB (before compresssion)  written to:

/Users/jianyuan/Personal/dump_endless.jfr

当然,我们可以手动停止正在运行的JFR任务:

➜ jcmd 12174 JFR.stop recording=3
12174:
Stopped recording 3.

分析JFR文件

JDK为我们提供了一个分析JFR的工具,叫JMC (Java Mission Control)。如果你Java的环境变量正确配置了,直接在命令行运行jmc就可以打开JMC程序。打开之前dump的一个jfr文件:
jmc jfr view

JMC根据内存,线程等分了多个Tab,根据你要定位的具体问题浏览不同的Tab。

文章同步发布在我的个人博客上,欢迎拍砖。
传送门: 使用JCMD采集JFR

posted @ 2018-08-23 17:37  jianyuan  阅读(1260)  评论(0编辑  收藏  举报