如何通过JFR获取内存视图中对象的详细信息?已配置JFR但无效
问题描述
我在JProfiler中观察到byte[]占用了最大内存(235MB),但缺乏足够细节,无法定位这些数组在程序中的具体位置以及关联的变量名。我尝试添加了JVM参数来采集更详细的内存信息,但未生效。
使用的JVM参数
'-XX:+FlightRecorder' \ '-XX:StartFlightRecording=duration=180s,settings=/opt/amazon/brazil-config/app/my_jfr_config.jfc,filename=myrecording.jfr' \
自定义JFR配置文件(my_jfr_config.jfc)
<?xml version="1.0" encoding="UTF-8"?> <configuration version="2.0" label="Continuous" description="Low overhead configuration safe for continuous use in production environments, typically less than 1 % overhead." provider="Oracle"> <event name="jdk.ObjectCount"> <setting name="enabled" control="memory-profiling-enabled-all">true</setting> <setting name="enabled" control="heap-statistics-enabled">true</setting> <setting name="period">everyChunk</setting> </event> </configuration>
使用的JDK版本
openjdk 11.0.20 2023-07-18 LTS
解决方案
你的JFR配置仅启用了jdk.ObjectCount事件,该事件只能统计对象数量,无法追踪对象的引用链和关联变量。要获取byte[]的详细内存信息,需调整JFR配置,启用堆快照或对象分配追踪相关事件。
1. 调整JFR配置
启用堆快照事件
在jfc配置中添加jdk.HeapDump事件,录制过程中生成堆快照,后续可通过JProfiler或jfr工具分析快照,查看byte[]的引用链和关联变量:
<event name="jdk.HeapDump"> <setting name="enabled">true</setting> <setting name="period">180s</setting> <!-- 与录制时长保持一致,按需调整 --> </event>
启用对象分配追踪
若需要更细粒度的分配位置信息,启用以下事件记录byte[]的创建位置:
<event name="jdk.ObjectAllocationInNewTLAB"> <setting name="enabled">true</setting> <setting name="threshold">0</setting> <!-- 记录所有分配,生产环境可调整阈值降低开销 --> </event> <event name="jdk.ObjectAllocationOutsideTLAB"> <setting name="enabled">true</setting> <setting name="threshold">0</setting> </event>
2. 使用JDK内置预定义配置
直接使用JDK自带的profile配置,该配置已包含内存分析所需的核心事件,无需自定义:
'-XX:+FlightRecorder' \ '-XX:StartFlightRecording=duration=180s,settings=profile,filename=myrecording.jfr' \
3. 额外排查步骤
- 检查
myrecording.jfr文件是否生成,若文件过小(几KB)说明录制未正常工作; - 确认启动参数中无冲突项(如
-XX:-FlightRecorder会禁用JFR); - 使用
jcmd <pid> JFR.check命令查看JFR录制状态,确认录制正在运行。
内容的提问来源于stack exchange,提问作者winfield
相关产品推荐
相关产品推荐

