用户可通过该项目将代码性能分析数据可视化为火焰图,直观展示代码执行时间分布。支持Linux perf_events、DTrace等多种工具捕获的堆栈数据,提供折叠堆栈、搜索高亮等功能,帮助快速定位性能瓶颈。【此简介由AI生成】
火焰图:可视化分析代码性能
主网站:http://www.brendangregg.com/flamegraphs.html
示例(点击可缩放):
点击某个框可将火焰图缩放到仅显示该栈帧。 要搜索并高亮所有匹配正则表达式的栈帧,请点击右上角的“搜索”按钮或按下 Ctrl-F。 默认情况下,搜索区分大小写,但可通过按下 Ctrl-I 或点击右上角的“ic”按钮切换此设置。
其他相关网站:
- ACMQ 和 CACM 上的火焰图文章:http://queue.acm.org/detail.cfm?id=2927301 http://cacm.acm.org/magazines/2016/6/202665-the-flame-graph/abstract
- 使用 Linux perf_events、DTrace、SystemTap 或 ktap 进行 CPU 分析:http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html
- 使用 XCode Instruments 进行 CPU 分析:http://schani.wordpress.com/2012/11/16/flame-graphs-for-instruments/
- 使用 Xperf.exe 进行 CPU 分析:http://randomascii.wordpress.com/2013/03/26/summarizing-xperf-cpu-usage-with-flame-graphs/
- 内存分析:http://www.brendangregg.com/FlameGraphs/memoryflamegraphs.html
- 其他示例、更新和资讯:http://www.brendangregg.com/flamegraphs.html#Updates
创建火焰图需三个步骤:
-
捕获栈信息
-
折叠栈信息
-
运行 flamegraph.pl
-
捕获栈信息 ================= 可使用 Linux perf_events、FreeBSD pmcstat (hwpmc)、DTrace、SystemTap 以及许多其他分析工具来捕获栈样本。具体可参见 stackcollapse-* 转换器。
Linux perf_events
使用 Linux perf_events(又称“perf”)捕获 60 秒内、99 赫兹频率的栈样本,包括用户级和内核级栈,覆盖所有进程:
# perf record -F 99 -a -g -- sleep 60
# perf script > out.perf
现在仅捕获 PID 181:
# perf record -F 99 -p 181 -g -- sleep 60
# perf script > out.perf
DTrace
使用 DTrace 以 997 Hertz 的频率捕获 60 秒的内核堆栈:
# dtrace -x stackframes=100 -n 'profile-997 /arg0/ { @[stack()] = count(); } tick-60s { exit(0); }' -o out.kern_stacks
使用 DTrace 以 97 Hertz 的频率为 PID 12345 捕获 60 秒的用户级堆栈:
# dtrace -x ustackframes=100 -n 'profile-97 /pid == 12345 && arg1/ { @[ustack()] = count(); } tick-60s { exit(0); }' -o out.user_stacks
对 PID 12345 以 97 Hertz 的频率进行 60 秒的用户级栈采样,包括在内核中花费的时间:
# dtrace -x ustackframes=100 -n 'profile-97 /pid == 12345/ { @[ustack()] = count(); } tick-60s { exit(0); }' -o out.user_stacks
如果应用程序有 ustack 辅助程序来包含已转换的帧(例如 node.js 帧;参见:http://dtrace.org/blogs/dap/2012/01/05/where-does-your-node-program-spend-its-time/),请将 ustack() 替换为 jstack()。用户级堆栈收集的速率特意设置为慢于内核级,这在使用 jstack() 时尤为重要,因为它需要执行额外的工作来转换帧。
- 折叠堆栈 ============== 使用 stackcollapse 程序将堆栈样本折叠成单行。提供的程序如下:
stackcollapse.pl:用于 DTrace 堆栈stackcollapse-perf.pl:用于 Linux perf_events 的 "perf script" 输出stackcollapse-pmc.pl:用于 FreeBSD pmcstat -G 堆栈stackcollapse-stap.pl:用于 SystemTap 堆栈stackcollapse-instruments.pl:用于 XCode Instrumentsstackcollapse-vtune.pl:用于 Intel VTune 分析stackcollapse-ljp.awk:用于 Lightweight Java Profilerstackcollapse-jstack.pl:用于 Java jstack(1) 输出stackcollapse-gdb.pl:用于 gdb(1) 堆栈stackcollapse-go.pl:用于 Golang pprof 堆栈stackcollapse-vsprof.pl:用于 Microsoft Visual Studio 分析stackcollapse-wcp.pl:用于 wallClockProfiler 输出
使用示例:
For perf_events:
$ ./stackcollapse-perf.pl out.perf > out.folded
For DTrace:
$ ./stackcollapse.pl out.kern_stacks > out.kern_folded
输出结果如下:
unix`_sys_sysenter_post_swapgs 1401
unix`_sys_sysenter_post_swapgs;genunix`close 5
unix`_sys_sysenter_post_swapgs;genunix`close;genunix`closeandsetf 85
unix`_sys_sysenter_post_swapgs;genunix`close;genunix`closeandsetf;c2audit`audit_closef 26
unix`_sys_sysenter_post_swapgs;genunix`close;genunix`closeandsetf;c2audit`audit_setf 5
unix`_sys_sysenter_post_swapgs;genunix`close;genunix`closeandsetf;genunix`audit_getstate 6
unix`_sys_sysenter_post_swapgs;genunix`close;genunix`closeandsetf;genunix`audit_unfalloc 2
unix`_sys_sysenter_post_swapgs;genunix`close;genunix`closeandsetf;genunix`closef 48
[...]
- flamegraph.pl ================ 使用 flamegraph.pl 渲染 SVG。
$ ./flamegraph.pl out.kern_folded > kernel.svg
使用折叠输入文件的一个优势(这也是它与 flamegraph.pl 分开的原因)是,你可以使用 grep 来查找感兴趣的函数。例如:
$ grep cpuid out.kern_folded | ./flamegraph.pl > cpuid.svg
提供的示例
Linux perf_events
其中包含了 Linux“perf script”的示例输出,已进行 gzip 压缩,文件名为 example-perf-stacks.txt.gz。生成的火焰图为 example-perf.svg:
您可以使用以下命令创建此火焰图:
$ gunzip -c example-perf-stacks.txt.gz | ./stackcollapse-perf.pl --all | ./flamegraph.pl --color=java --hash > example-perf.svg
这是我的典型工作流程:我会在目标机器上对分析数据进行 gzip 压缩,然后将其复制到我的笔记本电脑进行分析。由于我有数百个分析数据,所以会一直保持它们的 gzip 压缩状态!
由于此分析数据包含 Java,我使用了 flamegraph.pl --color=java 调色板。我还使用了 stackcollapse-perf.pl --all,它包含所有注释,可帮助 flamegraph.pl 为内核和用户级代码使用不同的颜色。生成的火焰图使用以下颜色规则:绿色 == Java,黄色 == C++,红色 == 用户模式原生代码,橙色 == 内核。
此分析数据来自对 vert.x 性能的分析。火焰图中还可以看到基准测试客户端 wrk。
DTrace
还包含了 DTrace 的示例输出 example-dtrace-stacks.txt,以及生成的火焰图 example-dtrace.svg:
您可以使用以下命令生成此图:
$ ./stackcollapse.pl example-stacks.txt | ./flamegraph.pl > example.svg
这源于一项特定的性能调查:Flame Graph 识别出 CPU 时间花费在 lofs 模块中,并对该时间进行了量化。
选项
有关选项,请参见 USAGE 消息(--help):
用法:./flamegraph.pl [选项] 输入文件 > 输出文件.svg
--title TEXT # 更改标题文本 --subtitle TEXT # 二级标题(可选) --width NUM # 图像宽度(默认值 1200) --height NUM # 每个帧的高度(默认值 16) --minwidth NUM # 省略较小的函数。以像素为单位,或使用 "%" 表示时间百分比(默认值 0.1 像素) --fonttype FONT # 字体类型(默认值 "Verdana") --fontsize NUM # 字体大小(默认值 12) --countname TEXT # 计数类型标签(默认值 "samples") --nametype TEXT # 名称类型标签(默认值 "Function:") --colors PALETTE # 设置调色板。可选值包括:hot(默认)、mem、io、wakeup、chain、java、js、perl、red、green、blue、aqua、yellow、purple、orange --bgcolors COLOR # 设置背景颜色。渐变选项包括 yellow(默认)、blue、green、grey;纯色使用 "#rrggbb" --hash # 颜色由函数名哈希值确定 --cp # 使用一致的调色板(palette.map) --reverse # 生成栈反转的火焰图 --inverted # 冰柱图 --flamechart # 生成火焰图(按时间排序,不合并栈) --negate # 切换差异色调(蓝<->红) --notes TEXT # 在 SVG 中添加注释说明(用于调试) --help # 此帮助消息
例如,
./flamegraph.pl --title="Flame Graph: malloc()" trace.txt > graph.svg
如示例所示,火焰图可以处理任何事件的跟踪,例如 malloc() 调用,前提是已收集栈跟踪信息。
一致的调色板
如果使用 --cp 选项,它将使用 $colors 选择并像往常一样随机生成调色板。任何后续使用 --cp 选项创建的火焰图都将使用相同的调色板映射。未来火焰图中的任何新符号都将使用 $colors 选择随机生成颜色。
如果不喜欢当前调色板,只需删除 palette.map 文件。
这使您能够在不同火焰图之间更改配色方案,从而使差异真正突出显示。
示例:
假设我们有两次捕获,一次是存在问题时的,另一次是正常工作时的(无论“它”指的是什么):
cat working.folded | ./flamegraph.pl --cp > working.svg
# this generates a palette.map, as per the normal random generated look.
cat broken.folded | ./flamegraph.pl --cp --colors mem > broken.svg
# this svg will use the same palette.map for the same events, but a very
# different colorscheme for any new events.
查看演示目录中的示例:
palette-example-working.svg
palette-example-broken.svg