Java Flight Record(JFR) 是 Oracle 发布的一款 JVM 监控工具。
JFR 不仅提供了远比其他工具详尽和全面的 JVM 数据,还没有太大的 overhead。
根据官方的说法,JFR 会有大概 2% 的性能损失。
使用 JRF 需要利用到 jcmd 命令行工具。
jcmd 7060 JFR.start name=MyRecording settings=profile delay=20s duration=2m filename=/tmp/profiling.jfr
上方命令中,
lib/jfr
目录下的 jfc 文件。其内容是以 xml 格式定义的监控配置。JFR 也可以一直保持运行。不指定 duration 的情况下,
jcmd 7060 JFR.start name=MyRecording settings=profile # 开始监控
jcmd 7060 JFR.check # 查看运行状态
jcmd 7060 JFR.dump filename=/tmp/profiling.jfr # 导出记录文件,并不会终止监控
jcmd 7060 JFR.stop # 停止监控
jcmd 7060 JFR.stop filename=/tmp/profiling.jfr # 停止并导出记录文件
随着 JFR 源代码迁移到 OpenJDK,开发者可以免费这项功能而无需付费。
自然地,-XX:+UnlockCommercialFeatures
也变得没有必要了。
java \
-Xmx1024m \
-Xlog:gc*=debug:file=gc.log:utctime,uptime,tid,level:filecount=10,filesize=128m \
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump.hprof \
-XX:StartFlightRecording=\
disk=true, \
dumponexit=true, \
filename=recording.jfr, \
maxsize=1024m,\
maxage=1d,\
settings=profile \
path-to-gc-roots=true \
OOMEGenerator
JDK Mission Control 是 Oracle 官方的 JFR 文件分析工具。
你可以到https://jdk.java.net/jmc/8/下载。
IntelliJ IDEA 的付费版提供了 JFR 支持。
你可以点击 IDEA 上方菜单的 Run -> Open Profiler Snapshot -> Open... 打开 jfr 文件。
(或者直接把 .jfr 文件拖进去)
不得不说,Oracle 确实不是一家注重产品界面设计的公司,JMC 的 flame view 做得有点丑。
IntelliJ IDEA 界面是好看,但是无法把火焰图保存成 SVG 格式。PNG 格式的图片不太方便查看栈太复杂的情况。
于是,有时候可能你需要用 https://github.com/chrishantha/jfr-flame-graph 生成一个 SVG 格式好看的火焰图。
Syntax : JFR.start [options]
Options:
delay (Optional) Length of time to wait before starting to record
(INTEGER followed by 's' for seconds 'm' for minutes or h' for
hours, 0s)
disk (Optional) Flag for also writing the data to disk while recording
(BOOLEAN, true)
dumponexit (Optional) Flag for writing the recording to disk when the Java
Virtual Machine (JVM) shuts down. If set to 'true' and no value
is given for filename, the recording is written to a file in the
directory where the process was started. The file name is a
system-generated name that contains the process ID, the recording
ID and the current time stamp. (For example:
id-1-2021_09_14_09_00.jfr) (BOOLEAN, false)
duration (Optional) Length of time to record. Note that 0s means forever
(INTEGER followed by 's' for seconds 'm' for minutes or 'h' for
hours, 0s)
filename (Optional) Name of the file to which the flight recording data is
written when the recording is stopped. If no filename is given, a
filename is generated from the PID and the current date and is
placed in the directory where the process was started. The
filename may also be a directory in which case, the filename is
generated from the PID and the current date in the specified
directory. (STRING, no default value)
maxage (Optional) Maximum time to keep the recorded data on disk. This
parameter is valid only when the disk parameter is set to true.
Note 0s means forever. (INTEGER followed by 's' for seconds 'm'
for minutes or 'h' for hours, 0s)
maxsize (Optional) Maximum size of the data to keep on disk in bytes if
one of the following suffixes is not used: 'm' or 'M' for
megabytes OR 'g' or 'G' for gigabytes. This parameter is valid
only when the disk parameter is set to 'true'. The value must not
be less than the value for the maxchunksize parameter set with
the JFR.configure command. (STRING, 0 (no max size))
name (Optional) Name of the recording. If no name is provided, a name
is generated. Make note of the generated name that is shown in
the response to the command so that you can use it with other
commands. (STRING, system-generated default name)
path-to-gc-root (Optional) Flag for saving the path to garbage collection (GC)
roots at the end of a recording. The path information is useful
for finding memory leaks but collecting it is time consuming.
Turn on this flag only when you have an application that you
suspect has a memory leak. If the settings parameter is set to
'profile', then the information collected includes the stack
trace from where the potential leaking object wasallocated.
(BOOLEAN, false)
settings (Optional) Name of the settings file that identifies which events
to record. To specify more than one file, use the settings
parameter repeatedly. Include the path if the file is not in
JAVA-HOME/lib/jfr. The following profiles are included with the
JDK in the JAVA-HOME/lib/jfr directory: 'default.jfc': collects a
predefined set of information with low overhead, so it has minimal
impact on performance and can be used with recordings that run
continuously; 'profile.jfc': Provides more data than the
'default.jfc' profile, but with more overhead and impact on
performance. Use this configuration for short periods of time
when more information is needed. Use none to start a recording
without a predefined configuration file. (STRING,
JAVA-HOME/lib/jfr/default.jfc)
Event settings and .jfc options can also be specified using the following syntax:
jfc-option=value (Optional) The option value to modify. To see available
options for a .jfc file, use the 'jfr configure' command.
event-setting=value (Optional) The event setting value to modify. Use the form:
<event-name>#<setting-name>=<value>
To add a new event setting, prefix the event name with '+'.
In case of a conflict between a parameter and a .jfc option, the parameter will
take precedence. The whitespace character can be omitted for timespan values,
i.e. 20s. For more information about the settings syntax, see Javadoc of the
jdk.jfr package.
Options must be specified using the <key> or <key>=<value> syntax.
Example usage:
$ jcmd <pid> JFR.start
$ jcmd <pid> JFR.start filename=dump.jfr
$ jcmd <pid> JFR.start filename=%s
$ jcmd <pid> JFR.start dumponexit=true
$ jcmd <pid> JFR.start maxage=1h,maxsize=1000M
$ jcmd <pid> JFR.start settings=profile
$ jcmd <pid> JFR.start delay=5m,settings=my.jfc
$ jcmd <pid> JFR.start gc=high method-profiling=high
$ jcmd <pid> JFR.start jdk.JavaMonitorEnter#threshold=1ms
$ jcmd <pid> JFR.start +HelloWorld#enabled=true +HelloWorld#stackTrace=true
$ jcmd <pid> JFR.start settings=user.jfc com.example.UserDefined#enabled=true
$ jcmd <pid> JFR.start settings=none +Hello#enabled=true
Note, if the default event settings are modified, overhead may exceed 1%%.