Java JFR 事件采样如何降低诊断开销
Java JFR(Java Flight Recorder)要降低诊断开销,重点不是把所有事件都关掉,而是把记录范围缩小到当前问题:持续观察优先使用 default.jfc,短时深挖再考虑 profile.jfc,周期采样用 period 拉开间隔,耗时事件用 threshold 过滤短调用,只有确实需要定位调用路径时才保留 stackTrace。
官方文档:https://docs.oracle.com/en/java/javase/26/docs/api/jdk.jfr/
- 持续记录先从
default.jfc开始,profile.jfc更适合短时分析。 period控制周期事件频率,threshold控制耗时事件的最低记录门槛。- 调参后要检查事件数量、字段和堆栈是否真的能回答问题。
先把 JFR 记录范围收窄
把 JFR 当成线上常驻诊断工具时,先用默认配置建立基线。Oracle 对两套预置配置的定位很清楚:default.jfc 记录量较克制,适合持续记录;profile.jfc 包含更多事件,适合需要更多信息的短时剖析。不要为了“可能有用”直接长期启用 profile。
# 中文注释:先用低开销配置记录 60 秒,文件写到当前目录 jcmdJFR.start name=baseline settings=default duration=60s filename=baseline.jfr # 中文注释:只有复现窗口很短、需要更多事件时才临时使用 profile jcmd JFR.start name=deep settings=profile duration=30s filename=deep.jfr
如果问题只与 CPU 消耗有关,可以进一步只打开采样事件,不要把锁、文件、网络和类加载事件全部叠加。配置应在录制启动前完成,这样记录从一开始就使用目标设置。

用 period、threshold 和堆栈开关控制数据量
周期采样不是越密越好。需要观察趋势时可以把 jdk.CPUSample 的周期设为 2 秒;只有在短暂复现窗口内,才考虑更密的周期。对持续时间事件,threshold 可以过滤掉低于门槛的调用,减少“记录很多、判断很少”的噪声。堆栈则要按定位需要开启,因为它比单个事件字段更重。
import jdk.jfr.Recording;
import java.nio.file.Path;
import java.time.Duration;
try (Recording recording = new Recording()) {
// 中文注释:CPU 采样每 2 秒取一次,适合先看趋势而非追逐瞬时尖峰
recording.enable("jdk.CPUSample")
.withPeriod(Duration.ofSeconds(2));
// 中文注释:只保留达到 20 毫秒的文件写入,并关闭无关堆栈
recording.enable("jdk.FileWrite")
.withThreshold(Duration.ofMillis(20))
.withoutStackTrace();
// 中文注释:设置完成后再启动,避免录制初段使用了错误配置
recording.setToDisk(true);
recording.start();
Thread.sleep(30_000L); // 中文注释:模拟一个有限复现窗口
recording.stop();
recording.dump(Path.of("jfr-sampled.jfr"));
} catch (InterruptedException ex) {
// 中文注释:收到中断时恢复中断标记,让上层决定是否结束诊断
Thread.currentThread().interrupt();
}
这段写法的边界是:period 只适用于周期事件,threshold 只对有持续时间的事件有意义;它们不会替代业务压测,也不会自动证明某个线程就是根因。若需要调用路径,再针对目标事件使用 withStackTrace(),不要全局打开。
用事件数量验证开销是否值得
调参后不要只看“生成了一个 .jfr 文件”。先确认文件里真的有目标事件,再判断字段和堆栈是否足够支持下一步。事件太少,说明周期或门槛过严;事件爆炸,说明范围、周期、阈值或堆栈开关过宽。
# 中文注释:只打印目标事件,先判断采样是否真的产生了记录 jfr print --events jdk.CPUSample,jdk.FileWrite jfr-sampled.jfr # 中文注释:查看录制的元信息,核对起止时间和配置线索 jfr metadata jfr-sampled.jfr | head -n 40
| 现象 | 优先调整 | 判断 |
|---|---|---|
| 事件数量过多 | 拉长 period、提高 threshold、关闭堆栈 | 先减少噪声,再看是否仍能定位 |
| 事件数量过少 | 缩短 period、降低 threshold 或扩大复现窗口 | 确认不是问题本身未发生 |
| 有事件但无法定位 | 只对目标事件开启 stackTrace | 避免把所有事件变成堆栈采样 |

常见问题
default.jfc 能不能直接替代所有 profiling?
不能。它适合持续记录的基础信号;需要更多事件时可以在短时间窗口使用 profile,或复制配置后只修改相关事件。
threshold 越大是不是越省开销?
通常会减少短耗时事件数量,但也可能漏掉大量频繁的小调用。应让门槛服务于问题边界,并用事件输出确认没有过滤过头。
为什么只调 period 仍然感觉记录很重?
可能是其他事件仍在记录,或堆栈信息带来了额外数据。先按事件名缩小范围,再单独决定哪些事件需要堆栈。
最终可以把规则固化为一张清单:持续观察用 default.jfc,短时复现才用 profile.jfc;周期事件调 period,耗时事件调 threshold,调用栈只给真正需要定位的事件;最后用 jfr print 检查记录是否足够。这样降低的是无效数据量,而不是牺牲诊断能力。
LiblibAI连续生成人物时长相总变怎么办?按参考图、特征词和种子排查
- 上一篇
- LiblibAI连续生成人物时长相总变怎么办?按参考图、特征词和种子排查
- 下一篇
- Python 3.14 template string 如何用于受控模板解析
-
- 文章 · java教程 | 58分钟前 | 故障排查 · Java教程 · 模块化 · ServiceLoader · SPI · 类加载器 · java SPI ServiceLoader ClassLoader module-info.java META-INF/services
- Java ServiceLoader 找不到实现类时先检查什么
- 490浏览 收藏
-
- 文章 · java教程 | 2小时前 | httpclient · Java教程 · 网络请求 · InputStream · 资源关闭 · java httpclient 流式读取 InputStream BodyHandlers.ofInputStream 大响应
- Java HttpClient BodyHandlers.ofInputStream 何时更合适
- 145浏览 收藏
-
- 文章 · java教程 | 4小时前 | 正则表达式 · 字符串处理 · pattern · Java教程 · 代码实践 · java Java正则表达式 Pattern.DOTALL 匹配换行 Pattern.MULTILINE
- Java Pattern DOTALL 开启后点号为何匹配换行
- 199浏览 收藏
-
- 文章 · java教程 | 7小时前 |
- Java Path normalize 和 toRealPath 有什么区别
- 298浏览 收藏
-
- 文章 · java教程 | 23小时前 | Java · BigDecimal · 数值比较 · java equals bigdecimal compareTo
- Java BigDecimal equals 为何和 compareTo 不一致
- 452浏览 收藏
-
- 文章 · java教程 | 1天前 | 异常处理 · 并发编程 · api设计 · Java教程 · CompletableFuture · java 异常处理 异步编程 completablefuture Handle 统一结果
- Java CompletableFuture handle 如何把异常转成统一结果
- 338浏览 收藏
-
- 文章 · java教程 | 1天前 | 集合 · Stream · Java教程 · Comparator · java Stream treemap comparator groupingBy 分组排序
- Java Stream groupingBy 后如何按自定义比较器输出分组
- 448浏览 收藏
-
- 文章 · java教程 | 1天前 | Java · nio · ByteBuffer · java nio ByteBuffer flip
- Java NIO ByteBuffer flip 后 limit 和 position 怎么变化
- 368浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 82次使用
-
- OpenCompass
- OpenCompass是上海AI实验室推出的开源大模型评测平台,提供CompassKit、CompassHub和CompassRank三大核心组件,支持LLM及多模态模型的一站式标准化评估与排行榜查询。
- 11次使用
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 243次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 166次使用
-
- AI Prompt Library
- 探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
- 100次使用
-
- Go Java 算法之字符串解码示例详解
- 2023-01-07 479浏览
-
- Go Java算法之单词搜索示例详解
- 2022-12-30 337浏览
-
- Gojava算法之括号生成示例详解
- 2023-02-22 128浏览
-
- GoJava算法之累加数示例详解
- 2023-01-07 149浏览
-
- GoJava算法最大单词长度乘积示例详解
- 2023-01-12 202浏览

