Async Profiler 与 JFR

共 17 题
📑 题目列表 17 题
#
★★★

1. Async Profiler 的采样原理,基于 perf_event 的 CPU 采样与 wall-clock 采样的差异,火焰图的解读要点如何?

Async Profiler 的采样原理:基于 perf_event 的 CPU 采样与 wall-clock 采样的差异,火焰图的解读要点是什么?

  • perf_event CPU 采样
  • wall-clock 采样
  • 火焰图解读

Async Profiler 采样式剖析的两种模式:1) CPU 采样(基于 perf_event 或 JVMTI):每 N 毫秒采样正在执行 CPU 指令的线程栈,反映 CPU 热点(只统计 CPU 上的时间);2) wall-clock 采样:采样所有线程的完整栈(无论 CPU 与否),反映线程时间去向(包括 I/O 等待、锁、sleep)。差异:CPU 采样只看 CPU 时间(等待不可见),wall 采样看全部时间(含等待)。火焰图解读要点:x 轴宽度表示采样占比,y 轴栈深;顶部宽 = 热点函数;CPU 火焰图看 CPU 热点,wall 火焰图看等待/阻塞;结合事件类型(cpu/alloc/lock/wall)解读问题类型。理解采样差异与火焰图解读是 async-profiler 使用核心。

CPU 采样看 CPU 热点,wall 采样看包括等待的全部时间。火焰图顶部宽度是热点信号,结合事件类型解读。

#
★★

2. async-profiler 的锁分析,lock 事件与 Contention

async-profiler 的锁分析:lock 事件与 Contention 如何理解?

  • lock 事件
  • 锁竞争(Contention)
  • 锁火焰图

async-profiler 的 lock 事件用于锁分析,采样线程等待锁(Contention)时的栈,定位锁竞争热点。lock 事件记录线程阻塞在锁获取(synchronized 块、JUC 锁)上的时间,火焰图(lock 火焰图)显示等待锁的比例与持锁路径。Contention 分析要点:1) 锁火焰图顶部宽 = 锁等待热点(哪个锁/哪个方法的锁竞争高);2) 结合持锁路径(谁持有锁、持锁期间调用栈)定位锁竞争根因;3) 区分锁等待(获取锁)与锁持有(持锁执行);4) 结合 JFR 的 jdk.JavaMonitorEnter/jdk.JavaMonitorWait 事件更精确。价值:定位频繁锁竞争、锁粒度问题、优化锁策略(减小锁范围、无锁、读写锁)。理解 lock 事件与 contention 是锁性能分析关键。

lock 事件采样锁等待,锁火焰图定位竞争热点。理解锁等待与持锁路径是锁优化关键。

#
★★

3. JFR 与 async-profiler 的互补使用

JFR 与 async-profiler 如何互补使用?

  • JFR 特点
  • async-profiler 特点
  • 互补场景

JFR 与 async-profiler 互补使用:JFR 是 JDK 内置、事件驱动、低开销,覆盖 JVM 内部事件(GC、JIT、锁、线程、异常),适合持续录制与监控(低开销、覆盖 JVM 内部);async-profiler 是采样剖析、高精度火焰图(CPU/alloc/lock/wall),适合按需深挖调用栈热点与火焰图。互补:1) 用 JFR 持续录制(低开销)获得 JVM 全局事件(GC、锁、异常),发现异常;2) 用 async-profiler 按需深挖(高精度火焰图)定位 CPU/分配/锁热点的具体代码路径;3) JFR 的 OldObjectSample 定位泄漏,async-profiler 的 alloc 火焰图看分配热点;4) 两者数据可交叉验证(时间对齐)。组合:JFR "发现与 JVM 内部",async-profiler "定位代码热点"。

JFR 低开销覆盖 JVM 内部,async-profiler 高精度火焰图定位代码。互补组合覆盖广泛诊断。

#
★★

4. async-profiler 在容器/生产环境的安装与权限(perf_event_paranoid、cap_sys_admin)

async-profiler 在容器/生产环境的安装与权限(perf_event_paranoid、cap_sys_admin)如何配置?

  • 安装方式
  • perf_event_paranoid
  • cap_sys_admin 权限

async-profiler 在容器/生产环境的安装与权限:1) 安装:下载 async-profiler 的 native 库(libasyncProfiler.so)+ 脚本,挂载到容器或安装到主机;2) perf_event_paranoid:CPU 采样依赖 perf_event,需把 perf_event_paranoid 设为 <=1(如 sysctl kernel.perf_event_paranoid=1),否则无法采样 perf 事件;3) cap_sys_admin/cap_perfmon:读取内核栈或使用 perf 需 CAP_SYS_ADMIN 或 CAP_PERFMON,容器需添加 capability(如 add: ['SYS_ADMIN'] 或 CAP_PERFMON);4) 容器内挂载 async-profiler 库与脚本,配置路径;5) 生产权限最小化:只给所需 capability,避免过度提权。理解安装与权限配置是 async-profiler 在容器/生产使用的关键(权限不足会导致采样失败或失败到 wall-clock)。

async-profiler 依赖 perf_event 权限与 native 库。理解 perf_event_paranoid、capability 与容器挂载是部署关键。

#
★★

5. JFR 事件的自定义与扩展

JFR 事件的自定义与扩展如何实现?

  • 自定义 JFR 事件
  • 注解定义事件
  • 事件录制

JFR 自定义事件:通过继承 jdk.jfr.Event 并配置注解定义自定义事件,如:@Label("MyEvent") @Name("my.app.MyEvent") class MyEvent extends Event { @Label("value") int value; }。使用:MyEvent e = new MyEvent(); e.value = 42; e.begin(); // 业务逻辑 e.end(); e.commit();(begin/end 记录耗时,commit 提交事件)。可配置:@Category(分类)、@Description(描述)、@Threshold、@StackTrace 等。通过 -XX:StartFlightRecording 或 JFR API 录制自定义事件,JMC/Streaming API 可消费。扩展价值:把业务语义作为 JFR 事件接入,与 JVM 事件统一,低开销、可关联。理解自定义事件是 JFR 扩展业务可观测性的关键。

自定义 JFR 事件通过继承 Event + 注解,begin/end/commit 记录。理解定义与录制是 JFR 扩展的关键。

#
★★

6. JFR 的 Streaming API 与实时监控

JFR 的 Streaming API 与实时监控如何应用?

  • JFR Streaming API
  • 实时事件流
  • 监控集成

JFR Streaming API(jdk.jfr.consumer 的 RecordingStream)允许在 JVM 内实时消费 JFR 事件流,无需转储文件。实时监控应用:1) 应用内订阅事件(GC、异常、线程、分配),实时处理(统计、日志、告警);2) 用 rs.onEvent("jdk.GCPhase", e -> {...}) 响应特定事件;3) 结合 enable(...).withPeriod 控制采样周期;4) 把 JFR 数据实时推送到监控系统(自定义 exporter)。Streaming 低开销(按需订阅)、可编程、实时。工程价值:实时监控 JVM 内部(GC 停顿、异常、锁),与外部监控集成,无需外部工具。理解 Streaming 的实时事件流与编程是对 JFR 实时监控的关键。

Streaming API 实时消费事件流,可编程接入监控。理解实时订阅与事件处理是 JFR 实时监控关键。

#
★★

7. JFR 的开销评估与生产环境配置

JFR 的开销评估与生产环境配置如何做?

  • JFR 开销
  • 生产配置
  • 开销控制

JFR 的开销评估与生产配置:1) 开销:JFR 默认/低配置开销低(约 1-2% CPU),profile 配置开销略高;开销与事件数量、采样频率、栈深相关;2) 评估:用基准/压测对比开启/关闭 JFR 的吞吐与延迟,确认开销可接受;3) 生产配置:用 -XX:StartFlightRecording=disk,settings=profile/default,maxage=...,maxsize=... 限制录制窗口与文件大小;用 -XX:FlightRecorderOptions 配置缓冲、栈深;按需用 jcmd JFR.start 动态开启;4) 控制开销:合理设置事件阈值(低价值事件设高阈值)、限制 stack 深度、控制采样频率;5) 监控 JFR 自身开销。生产长期录制用低开销配置,避免影响性能。理解开销评估与配置是生产使用 JFR 的关键。

JFR 开销与事件/采样/栈深相关,生产用低开销配置并限制窗口。理解开销评估与配置是关键。

#
★★

8. JFR 的事件流模式,jdk.jfr.consumer 的实时事件流与 JMC 分析的工程组合如何?

JFR 的事件流模式:jdk.jfr.consumer 的实时事件流与 JMC 分析的工程组合如何?

  • 实时事件流
  • JMC 分析
  • 工程组合

JFR 的事件流模式:jdk.jfr.consumer 提供实时事件流(RecordingStream)与离线事件解析(RecordingFile)。工程组合:1) 实时事件流:用 RecordingStream 在 JVM 内实时消费事件(GC、异常),实现实时监控与告警;2) 离线分析:用 JFR 录制文件,结合 JMC 可视化分析(CPU、GC、线程、内存);3) 组合流程:实时流用于"发现异常"(实时监控),异常时转储 JFR 文件,用 JMC 深入分析(定位根因);4) 也可用 Streaming API 把事件实时推送到监控,JMC 对历史文件做详细分析。价值:实时流监控 + JMC 深入分析互补,覆盖"实时发现"与"深入定位"。理解事件流与 JMC 的组合是 JFR 工程应用关键。

实时流监控发现,JMC 分析定位。两者组合覆盖实时与深入诊断。

#
★★

9. JFR 的飞行记录与事件流,录制配置、转储与分析工作流(JMC/异步转储)如何?

JFR 的飞行记录与事件流:录制配置、转储与分析工作流(JMC/异步转储)如何?

  • 录制配置
  • 转储
  • 分析工作流

JFR 飞行记录(Flight Recorder)工作流:1) 录制配置:用 -XX:StartFlightRecording 启动录制(disk/file/settings/maxage/maxsize),或 jcmd JFR.start 动态开启;2) 转储:用 jcmd JFR.dump 把内存缓冲转储到文件(异步转储,不阻塞应用),或定时/异常触发转储;3) 分析:用 JMC 打开 jfr 文件可视化分析(CPU/GC/线程/内存/方法采样),或 JFR Streaming API 分析;4) 异步转储:jcmd JFR.dump filename=... 生成文件,用于事后分析。工作流:诊断时启动录制(或已有持续录制)→ 发生问题 → 异步转储 → JMC 分析定位根因。事件流(Streaming)用于实时监控。理解录制、转储、分析工作流是 JFR 使用核心。

JFR 工作流是录制→转储→分析。理解 jcmd JFR.dump 异步转储与 JMC 分析是关键。

#
★★

10. JFR 的自动转储触发(JFR.dump、定时转储、异常/GC 触发)与归档管理

JFR 的自动转储触发(JFR.dump、定时转储、异常/GC 触发)与归档管理如何做?

  • 自动转储触发
  • 定时/异常/GC 触发
  • 归档管理

JFR 自动转储触发与归档管理:1) 手动转储:jcmd JFR.dump 随时转储;2) 定时转储:-XX:StartFlightRecording=...,maxage=... 或配置定时 dump(如每隔一段时间转储并归档);3) 异常/GC 触发:通过 -XX:+CrashOnOutOfMemoryError 或 JFR 的 JFR.dump 结合 OOM 处理,或配置触发条件(如 -XX:FlightRecorderOptions=disk=truemaxage 自动滚动);4) 归档管理:转储文件可能大,需定期归档(对象存储/中央存储)、设置保留策略(保留最近 N 份/时间窗口)、清理旧文件,避免磁盘占满。工程实践:持续录制(限制窗口)+ 事件触发转储(异常/定时)+ 归档清理。价值是保留诊断数据且不占磁盘。理解触发与归档是 JFR 生产管理关键。

JFR 转储分手动/定时/触发,归档管理防止磁盘占满。理解触发与归档是生产 JFR 管理关键。

#

11. async-profiler 的火焰图生成与分析

async-profiler 的火焰图如何生成与分析?

  • 火焰图生成
  • 分析
  • 格式

async-profiler 生成火焰图:采集后把数据(如 async-profiler -d 30 -e cpu -f /tmp/profile.html)生成 SVG/HTML 火焰图(collapsed 格式 + FlameGraph 脚本),或生成 jfr 文件用 JMC 分析。命令:-e cpu(CPU)、-e alloc(分配)、-e lock(锁)、-e wall(wall-clock)、-d 秒数(时长)、-f 文件(输出)。分析要点:1) 顶部宽 = 热点函数;2) 结合事件类型(cpu 看 CPU、alloc 看分配、lock 看锁、wall 看等待)解读问题;3) 用 diff 火焰图对比版本回归;4) 下钻到代码行(含源码)。价值:可视化调用栈热点,直观定位性能瓶颈。理解生成命令与分析要点是 async-profiler 使用核心。

async-profiler 生成火焰图用 -e 指定事件、-d 时长、-f 输出。分析看顶部宽与事件类型。

#

12. Async Profiler 的 allocation 与 lock 剖析,Java 与 native 栈混合采样的限制如何?

Async Profiler 的 allocation 与 lock 剖析:Java 与 native 栈混合采样的限制如何理解?

  • allocation 剖析
  • lock 剖析
  • Java/native 栈混合限制

async-profiler 的 allocation 剖析采集对象分配点(分配热点),lock 剖析采集锁等待(锁竞争)。Java 与 native 栈混合采样的限制:1) 采样栈可能混合 Java 帧与 native 帧(如 JNI 调用、native 分配),native 栈的符号解析依赖系统符号(perf、debug symbols),容器内可能无法解析 native 栈;2) 分配热点在 native 层(如 JIT 分配的 trampoline、GC 内部)可能无法完整归因到 Java 调用点;3) lock 剖析对 native 锁/系统锁的采样受限于权限与符号;4) 混合栈在火焰图展示时 native 帧可能不完整或缺失。理解这些限制:Java 栈分析可靠,native 层需结合系统工具(perf/bpftrace)与权限配置。价值是知道采样的边界,避免误读。

Java/native 混合栈采样受 native 符号与权限限制。理解限制避免误读分配/锁热点的 native 部分。

#

13. async-profiler 的火焰图解读,CPU/分配/锁火焰图分别定位什么问题?

async-profiler 的火焰图解读:CPU/分配/锁火焰图分别定位什么问题?

  • CPU 火焰图
  • 分配火焰图
  • 锁火焰图

async-profiler 火焰图按事件类型定位不同问题:1) CPU 火焰图(-e cpu):采集线程在 CPU 上的栈,定位 CPU 热点(CPU 密集、高耗 CPU 的方法),火焰图顶部宽 = CPU 热点;2) 分配火焰图(-e alloc):采集对象分配点,定位分配热点(高分配、GC 压力来源),火焰图顶部宽 = 分配热点;3) 锁火焰图(-e lock):采集锁等待栈,定位锁竞争(锁等待热点、持锁路径),火焰图顶部宽 = 锁竞争热点。各自定位:CPU 火焰图看"CPU 花在哪",分配火焰图看"内存分配在哪",锁火焰图看"锁等待在哪"。结合事件类型解读,针对不同性能问题(CPU/内存/锁)。理解各火焰图定位问题是性能分析关键。

CPU 火焰图定位 CPU 热点,分配火焰图定位分配热点,锁火焰图定位锁竞争。按事件类型选择分析。

#

14. JFR 与 async-profiler 的配合,CPU 采样与事件触发的场景分工如何?

JFR 与 async-profiler 的配合:CPU 采样与事件触发的场景分工如何?

  • JFR 事件触发
  • async-profiler CPU 采样
  • 场景分工

JFR 与 async-profiler 配合的场景分工:1) JFR(事件驱动):覆盖 JVM 内部事件(GC、锁、异常、线程、JIT),常用于持续监控、按事件触发(如 GC 停顿、异常、OOM 触发转储),定位 JVM 内部问题;2) async-profiler(CPU 采样):高精度采样 CPU 热点,生成火焰图,用于按需深挖代码级热点(CPU 密集、分配、锁竞争)。分工:JFR 负责"发现与 JVM 内部事件"(持续、低开销、事件触发),async-profiler 负责"按需深挖代码热点"(CPU 采样、火焰图)。流程:JFR 持续监控发现异常(事件触发)→ 用 async-profiler 深挖 CPU/分配/锁热点定位代码。CPU 采样用 async-profiler,事件触发用 JFR,互补覆盖。

JFR 事件驱动发现 JVM 内部,async-profiler CPU 采样深挖代码。分工是"发现"与"定位"。

#

15. async-profiler 的分配剖析,allocation profiling 与 GC 关联分析如何?

async-profiler 的分配剖析:allocation profiling 与 GC 关联分析如何做?

  • allocation profiling
  • 分配速率
  • GC 关联

async-profiler 的 allocation profiling(-e alloc)采样对象分配点,统计分配频率与体积,生成分配火焰图,定位热点分配(哪些代码分配大量对象)。与 GC 关联分析:1) 分配速率与 GC 频率相关:高分配速率 → 快速填满新生代 → 频繁 Minor GC;2) 分配热点定位 GC 压力来源:若 GC 频繁,用分配火焰图找分配热点,减少分配(对象复用、池化、避免装箱)可降低 GC 压力;3) 结合 GC 日志/JFR 的分配速率交叉验证:JFR 的 jdk.ObjectAllocationSample 事件记录分配,GC 日志显示 GC 频率;4) 分配热点 + 存活率:分配热点且对象存活(OldObjectSample)指示泄漏,只分配短命则高分配率。理解分配剖析与 GC 关联是优化 GC 压力的关键。

分配剖析定位分配热点,与 GC 频率/存活率关联可定位 GC 压力来源。理解关联是优化分配与 GC 的关键。

#

16. async-profiler 的 wall-clock 模式,阻塞与 IO 等待的采样分析如何?

async-profiler 的 wall-clock 模式:阻塞与 IO 等待的采样分析如何做?

  • wall-clock 模式
  • 阻塞与 IO 等待
  • 采样分析

async-profiler 的 wall-clock 模式(-e wall)采样所有线程的完整栈(无论是否在 CPU 上),用于分析阻塞与 IO 等待:1) 采样包括线程在等待(sleep、IO、锁、网络)时的栈,反映"时间花在哪"(非 CPU 时间);2) 定位阻塞:wall 火焰图顶部宽 = 线程在等待某个操作(如 socket read、file read、锁);3) 区分等待类型:看栈中方法(socketRead、fileRead、LockSupport.park)判断是网络/磁盘/锁等待;4) 结合 on-cpu 与 off-cpu:wall 覆盖 off-cpu(等待),CPU 火焰图只覆盖 on-cpu,两者结合完整分析。wall 模式适合定位 I/O 密集、阻塞、锁等待导致的性能问题(CPU 不高但延迟高)。理解 wall 模式是阻塞/IO 分析关键。

wall 模式采样含等待栈,定位阻塞与 IO 等待。结合 CPU 火焰图完整分析 on/off-cpu 时间。

#

17. 火焰图的差分对比(diff flamegraph)如何定位版本回归

火焰图的差分对比(diff flamegraph)如何定位版本回归?

  • diff flamegraph
  • 版本对比
  • 回归定位

火焰图差分对比(diff flamegraph)对比两个版本的火焰图,定位性能回归:1) 生成两个版本的火焰图(如旧版本/新版本,用相同的剖析配置与事件);2) 用 diff 工具(如 Brendan Gregg 的 diff-flamegraph.pl 或 async-profiler 的 diff 功能)对比,红色表示新版本占比增加(回归/变慢),蓝色表示占比减少(优化);3) 通过对比热点函数的宽度变化,快速定位"哪个方法/调用路径在新版本中变慢(出现或膨胀)";4) 结合 diff 定位数据结构变化、算法变更、JIT 差异导致的回归。适用:版本发布前后的性能对比,定位性能回归的根因。理解 diff 火焰图的红色/蓝色语义与对比方法是版本回归定位的关键。

diff 火焰图用红/蓝标识新旧占比变化,定位版本回归热点。理解对比语义是关键。