You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Async Profiler分析Chronicle JLBH基准测试异常值

针对JLBH基准测试异常值的性能分析方法

以下是几种针对99分位以上延迟尖峰的分析方案,结合你已有的工具和Java生态的其他手段:

1. 基于JLBH回调触发Async Profiler定向采样

Chronicle JLBH允许在每个测试迭代中插入自定义逻辑,你可以借此在检测到慢操作时触发Async Profiler的精准采样:

  • 在JLBH测试代码中,每次完成业务操作并计算耗时后,判断是否超过20微秒阈值;
  • 满足条件时调用Async Profiler的Java API启动采样(指定wall模式,采样间隔设为1纳秒以保证细节捕获),持续采样1-2毫秒后停止;
  • 多次捕获后,Async Profiler生成的火焰图或调用栈报告会集中展示慢操作发生时的执行路径。
    示例代码片段:
JLBH jlbh = new JLBHBuilder()
    .warmUpIterations(10000)
    .iterations(100000)
    .throughput(1000000)
    .recordAfterWarmup(true)
    .build();

jlbh.start(() -> {
    long start = System.nanoTime();
    // 执行你的业务操作
    long duration = System.nanoTime() - start;
    if (duration > 20_000) { // 20微秒阈值
        AsyncProfiler profiler = AsyncProfiler.getInstance();
        profiler.start("wall,threads", 1); // 1纳秒间隔采样wall时间与线程状态
        try {
            Thread.sleep(1); // 采样1毫秒
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        profiler.stop();
        profiler.dumpFlameGraph("slow-op-flame-" + System.currentTimeMillis() + ".svg");
    }
});

2. 利用JFR自定义事件定位异常时段

Java Flight Recorder(JFR)低开销的事件捕获能力,结合自定义事件可以精准关联慢操作的上下文:

  • 定义JFR自定义事件类,包含耗时、线程ID等关键信息:
@Name("com.example.SlowOperation")
@Label("Slow Operation Detected")
public class SlowOperationEvent extends Event {
    @Label("Duration (ns)")
    public long duration;
}
  • 在JLBH的测试逻辑中,当耗时超过阈值时提交该事件:
if (duration > 20_000) {
    SlowOperationEvent event = new SlowOperationEvent();
    event.duration = duration;
    event.commit();
}
  • 启动基准测试时添加JFR参数:-XX:StartFlightRecording=filename=slow-ops.jfr,duration=60s;
  • 用Java Mission Control(JMC)打开录制文件,过滤出SlowOperation事件,查看事件发生前后的线程状态、GC活动、锁竞争、系统调用等细节,直接定位延迟根源。

3. 触发式线程转储捕获即时调用栈

当检测到慢操作时,立刻生成线程转储,直接查看当时的执行路径:

  • 在JLBH回调中,当耗时超过阈值时,通过代码生成线程转储文件:
if (duration > 20_000) {
    try (PrintWriter writer = new PrintWriter(new File("slow-thread-" + System.currentTimeMillis() + ".txt"))) {
        Thread.getAllStackTraces().forEach((thread, stack) -> {
            writer.println("Thread: " + thread.getName());
            for (StackTraceElement elem : stack) {
                writer.println("\t" + elem);
            }
        });
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  • 多次捕获后,对比多个转储文件,找出共同的阻塞点或热点方法,比如锁等待、IO操作、JIT编译等场景。

4. 排查系统级干扰因素

99分位以上的延迟往往和系统层面的因素相关,需结合系统工具交叉验证:

  • GC日志:添加-Xlog:gc*:file=gc.log:time,level参数,查看延迟尖峰是否与GC停顿(尤其是Full GC)时间重合;
  • 系统监控:用vmstat监控上下文切换、内存使用,iostat监控磁盘IO,sar -n DEV监控网络IO,确认延迟尖峰时是否有系统指标异常;
  • perf工具:用perf record -g -p <pid>记录进程CPU事件,通过perf report查看内核级瓶颈,比如调度延迟、系统调用耗时过高等。

内容的提问来源于stack exchange,提问作者Abidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:42:09