JFR 能记录 JVM 的哪些运行状态、怎么读?这篇用一个有锁争用的小程序实际录制,看文件大小、事件种类、具体事件字段和配置(JMX 与 NMT 在后面,JFR 与线程转储互补)。
[0.189s][info][jfr,startup] Started recording 1. No limit specified, using maxsize=250MB as default. | [0.189s][info][jfr,startup] | [0.189s][info][jfr,startup] Use jcmd 64663 JFR.dump name=1 to copy recording data to file. | app done 记录文件 rec.jfr 大小 575 KB
Version: 2.1 Chunks: 1 Start: 2026-10-03 08:40:11 (UTC) Duration: 3 s jdk.GCPhaseParallel 6806 172577 jdk.PromoteObjectInNewPLAB 955 16079 jdk.NativeLibrary 946 78946 jdk.ObjectAllocationSample 900 12699 jdk.SystemProcess 805 82171 jdk.ModuleExport 505 4912 jdk.BooleanFlag 490 14424 jdk.ActiveSetting 360 10031 jdk.TenuringDistribution 330 3364 jdk.JavaMonitorEnter 240 5272 jdk.LongFlag 162 5092 jdk.ModuleRequire 153 1377 共 185 种事件产生了记录
[jdk.GarbageCollection] 共 22 条;前 3 条的关键字段:
jdk.GarbageCollection {
startTime = 16:40:11.122 (2026-10-03)
duration = 1.22 ms
gcId = 1
name = "G1New"
cause = "G1 Evacuation Pause"
sumOfPauses = 1.22 ms
longestPause = 1.22 ms
eventThread = "VM Thread" (osThreadId = 18691)
}
[jdk.JavaMonitorEnter] 共 240 条;前 2 条的关键字段:
jdk.JavaMonitorEnter {
startTime = 16:40:11.067 (2026-10-03)
duration = 49.8 ms
monitorClass = java.lang.Object (classLoader = bootstrap)
previousOwner = "holder" (javaThreadId = 33)
address = 0x75E8CF2E60
eventThread = "worker-3" (javaThreadId = 32)
stackTrace = [
App.lambda$main$0(long) line: 5
java.lang.Thread.run() line: 1583
]
}
[jdk.ExecutionSample] 共 0 条;前 0 条的关键字段: jdk.ExecutionSample:default = {'enabled': 'true', 'period': '20 ms'};profile = {'enabled': 'true', 'period': '10 ms'}
jdk.JavaMonitorEnter:default = {'enabled': 'true', 'stackTrace': 'true', 'threshold': '20 ms'};profile = {'enabled': 'true', 'stackTrace': 'true', 'threshold': '10 ms'}