jmc
jmc(Java Mission Control)是JDK自带的一个图形界面监控工具,监控信息非常全面。JMC打开性能日志后,主要包括一般信息、内存、代码、线程、I/O、系统、事件 功能。

JMC的最主要的特征就是JFR(Java Flight Recorder),是基于JAVA的飞行记录器,JFR的数据是一些列JVM事件的历史纪录,可以用来诊断JVM的性能和操作,收集后的数据可以使用JMC来分析。
启动JFR
在商业版本上面,JFR默认是关闭的,可以通过在启动时增加参数 -XX:+UnlockCommercialFeatures -XX:+FlightRecorder 来启动应用。启动之后,也只是开启了JFR特性,但是还没有开始进行事件记录。这就要通过GUI和命令行了。
-
通过Java Mission Control启动JFR
打开Java Mission Control点击对应的JVM启动即可,事件记录有两种模式(如果选择第2种模式,那么JVM会使用一个循环使用的缓存来存放事件数据):
- 记录固定一段时间的事件(比如:1分钟)
- 持续进行记录
-
通过命令行启动JFR
通过在启动的时候,增加参数:
-XX:+FlightRecorderOptions=string来启动真正地事件记录,这里的string可以是以下值(下列参数都可以使用jcmd命令,在JVM运行的时候进行动态调整,参考地址):name=name:标识recording的名字(一个进程可以有多个recording存在,它们使用名字来进行区分)defaultrecording=<ture|false>:是否启动recording,默认是false,我们要分析,必须要设置为truesetting=paths:包含JFR配置的文件名字delay=time:启动之后,经过多长时间(比如:30s,1h)开始进行recordingduration=time:做多长时间的recordingfilename=path:recordding记录到那个文件里面compress=<ture|false>:是否对recording进行压缩(gzip),默认为falsemaxage=time:在循环使用的缓存中,事件数据保存的最大时长maxsize=size:事件数据缓存的最大大小(比如:1024k,1M)
常用JFR命令
-
启动recording
命令格式:
jcmd process_id JFR.start [options_list],其中options_list就是上述的参数值。 -
dump出循环缓存中的数据
命令格式:
jcmd process_id JFR.dump [options_list],其中options_list参数的可选值如下:name=name:recording的名字recording=n:JFR recording的数字(一个标识recording的随机数)filename=path:dump文件的保存路径
-
查看进程中所有recording
命令格式:
jcmd process_id JFR.check [verbose],不同recording使用名字进行区分,同时JVM还为它分配一个随机数。 -
停止recording
命令格式:
jcmd process_id JFR.stop [options_list],其中options_list参数的可选值如下:name=name:要停止的recording名字recording=n:要停止的recording的标识数字discard=boolean:如果为true,数据被丢弃,而不是写入下面指定的文件当中filename=path:写入数据的文件名称
命令启动JFR案例
- 第一步:创建一个包含了你自己配置的JFR模板文件(
template.jfc)。运行jmc, 然后Window->Flight Recording Template Manage菜单。准备好档案后,就可以导出文件,并移动到要排查问题的环境中

-
第二步:由于JFR需要JDK的商业证书,这一步需要解锁jdk的商业特性
[root@localhost bin]# jcmd 12234 VM.unlock_commercial_features 12234: Commercial Features already unlocked. -
第三步:最后你就可以启动JFR,命令格式如下:
jcmd <PID> JFR.start name=test duration=60s [settings=template.jfc] filename=output.jfr 上述命令立即启动JFR并开始使用
template.jfc(在$JAVA_HOME/jre/lib/jfr下有default.jfc和profile.jfc模板)的配置收集60s的JVM信息,输出到output.jfr中。一旦记录完成之后,就可以复制.jfr文件到你的工作环境使用jmc GUI来分析。它几乎包含了排查jvm问题需要的所有信息,包括堆dump时的异常信息。使用案例如下:[root@localhost bin]# jcmd 12234 JFR.start name=test duration=60s filename=output.jfr 12234: Started recording 6. The result will be written to: /root/zookeeper-3.4.12/bin/output.jfr [root@localhost bin]# ls -l -rw-r--r-- 1 root root 298585 6月 29 11:09 output.jfr
JFR(Java Flight Recorder)
- Java Mission Control的最主要的特征就是Java Flight Recorder。正如它的名字所示,JFR的数据是一些列JVM事件的历史纪录,可以用来诊断JVM的性能和操作
- JFR的基本操作就是开启哪些事件(比如:线程由于等待锁而阻塞的事件)。当开启的事件发生了,事件相关的数据会记录到内存或磁盘文件上。记录事件数据的缓存是循环使用的,只有最近发生的事件才能够从缓存中找到,之前的都因为缓存的限制被删除了。Java Mission Control能够对这些事件在界面上进行展示(从JVM的内存中读取或从事件数据文件中读取),我们可以通过这些事件来对JVM的性能进行诊断
- 事件的类型、缓存的大小、事件数据的存储方式等等都是通过JVM参数、Java Mission Control的GUI界面、jcmd命令来控制的。JFR默认是编译进程序的,因为它的开销很小,一般来说对应用的影响小于1%。不过,如果我们增加了事件的数目、修改了记录事件的阈值,都有可能增加JFR的开销
JFR概况
下面对GlassFish web服务器进行JFR记录的例子,在这个服务器上面运行着在第2章介绍的servlet。Java Mission Control加载完JFR获取的事件之后,大概是下面这个样子:

我们可以看到,通过上图可以看到:CPU使用率,Heap使用率,JVM信息,System Properties,JFR的记录情况等等。
JFR内存视图
Java Mission Control 可以看到非常多的信息,下图只显示了一个标签的内容。下图显示了JVM 的内存波动非常频繁,因为新生代经常被清除(有意思的是,head的大小并没有增长)。下面左边的面板显示了最近一段时间的垃圾回收情况,包括:GC的时长和垃圾回收的类型。如果我们点击一个事件,右边的面板会展示这个事件的具体情况,包括:垃圾垃圾回收的各个阶段及其统计信息。从面板的标签可以看到,还有很多其它信息,比如:有多少对象被清除了,花了多长时间;GC算法的配置;分配的对象信息等等。在第5章和第6章中,我们会详细介绍。

JFR 代码视图
这张图也有很多tab,可以看到各个包的使用频率和类的使用情况、异常、编译、代码缓存、类加载情况等等:

JFR事件视图
下图显示了事件的概述视图:

















