CPU Flame Graphs

确定 CPU 忙的起因是性能剖析的惯例工作,这通常波及剖析堆栈跟踪。以固定速率采样剖析是查看哪些代码门路是热门代码(On-CPU)的毛糙但无效的办法。它通常通过创立一个工夫中断来收集以后程序计数器、函数地址或整个堆栈回溯,并将这些中断转换为可读的摘要报告。

剖析数据可能长数千行,难以了解。火焰图是采样堆栈跟踪的可视化成果,可疾速辨认热代码门路。无关 CPU 剖析以外的此可视化成果的应用,请参阅Flame Graphs主页。

火焰图可与任何操作系统上的任何 CPU 探查器一起应用。我的示例应用 Linux perf_events、DTrace、SystemTap 和 ktap。无关其余探查器示例,请参阅Updates列表;无关火焰图软件,请参阅 github。

在此页面上,我将介绍和解释 CPU 火焰图,列出创立它们的通用阐明,而后探讨特定语言的生成。

目录:

  1. Problem  2. Flame Graph  3. Description  4. Instructions  5. Examples  6. C  7. C++  8. Java  9. Node.js  10. Other Languages  11. Other Uses  12. Background  13. References
  1. Problem

在这里, 我应用 Linux perf_events (又名 "perf" 命令) 来剖析正在耗费 Cpu 的 bash 程序:

perf record 命令以 99 赫兹 (-F 99) 采样,在咱们的指标 PID (-p 13204) 上采样,并捕捉堆栈跟踪 (-g --),用于调用图形信息。

perf report 命令在将数百个堆栈跟踪样本汇总为文本。相似的代码门路是一起,摘要显示为树形图,每个叶上都有百分比。从左上到右下读取门路,该门路遵循代码门路的先人(及其堆栈跟踪示例)。百分比必须相乘,以确定残缺堆栈跟踪的相对频率。

显示的第一个堆栈do_redirection_internal())仅占样本的 2%。下一个堆栈跟踪(execute_builtin_or_function(),1%。因而,在浏览了这个文本屏幕后,咱们只能占到样本的3%。为了理解 CPU 的大部分工夫破费在哪里,咱们心愿理解超过 50% 的代码门路。咱们可能须要做更多的浏览。

Too Much Data

上述输入已被截断,仅显示超过 8,000 行输入中的 45 行。可视化的残缺输入如下所示:

你能看到后面两个堆栈吗?他们在左上角。(Other versions: text, larger JPG.)

有时,CPU 工夫的大部分位于单个代码门路中,perf 报表在单个屏幕上轻松汇总此内容。然而,您通常须要浏览许多屏幕全文能力理解配置文件,这既耗时又乏味。

  1. The Flame Graph

当初,咱们用火焰图显示雷同数据:

如果您的浏览器中遇到问题,请尝试间接 SVG 或 PNG 版本。

应用火焰图时,所有数据都同时在屏幕上,最热的代码门路作为最宽的函数立刻不言而喻。

  1. Description

我会认真解释这一点:它可能看起来相似于来自探查器的其余可视化成果,但它是不同的。

  • 每个框示意堆栈中的函数(a "stack frame")。
  • y 轴显示堆栈深度(number of frames on the stack)。顶部框显示 on-CPU 的函数。上面是先人函数。函数下方的函数是它的父函数,就像后面显示的堆栈跟踪一样。(某些火焰图实现偏向于反转程序并应用"冰柱布局",因而火焰看起来颠倒过去。
  • x 轴逾越样本总体。它不显示工夫从左到右的传递,就像大多数图形一样。从左到右排序没有意义(按字母程序排序以最大化帧合并)。
  • 框的宽度显示它在 On-CPU 或 On-CPU 的先人的一部分的总工夫(基于样本计数)。具备宽框的函数在执行时可能比应用窄框的函数耗费更多的 CPU,或者,它们可能只是被调用更频繁。未显示呼叫计数(或通过采样已知)。
  • 如果多个线程同时运行和采样,样本计数可能会超过已用工夫。

火焰图色彩不固定,通常随机筛选为寒色(反对其余有意义的调色板)。此可视化成果称为"火焰图",因为它首次用于显示 CPU 上的热内容,并且,它看起来像火焰。它也是交互式的:鼠标悬停在SVG上以显示细节,而后单击以缩放。

./flamegraph.pl --color=io --title="Off-CPU Time Flame Graph" --countname=us

  1. Instructions

火焰图FlameGraph tool工具和阐明的代码在 github 上。这是一个简略的 Perl 程序,输入 SVG。它们分三个步骤生成:

1.  Capture stacks2.  Fold stacks3.  flamegraph.pl

第一步是应用您抉择的探查器。无关应用 perf、DTrace、SystemTap 和 ktap 的一些示例,请参阅下文。

第二步生成基于行的输入文件便于flamegraph.pl读取,也能够进行 grep'd 以筛选感兴趣的函数。有一组简略的 Perl 程序来做到这一点,名为 stackcollapse*.pl,用于解决来自不同探查器的输入。

perf

Linux perf_events具备多种性能,包含 CPU 采样。应用它来采样所有 CPU 并生成火焰图:

# git clone https://github.com/brendangregg/FlameGraph  # or download it from github# cd FlameGraph# perf record -F 99 -a -g -- sleep 60# perf script | ./stackcollapse-perf.pl > out.perf-folded# ./flamegraph.pl out.perf-folded > perf-kernel.svg

perf record 命令在所有 CPU (-a) 上以 99 赫兹 (-F 99) 的速度采样,捕捉堆栈跟踪,以便当前能够生成函数先人的调用图 (-g)。示例保留在 perf.data 文件中,由 perf script 读取。

我创立两头文件perf-folded,使其在从同一数据创立多个过滤火焰图时速度更快一些。例如:

# perf script | ./stackcollapse-perf.pl > out.perf-folded# grep -v cpu_idle out.perf-folded | ./flamegraph.pl > nonidle.svg# grep ext4 out.perf-folded | ./flamegraph.pl > ext4internals.svg# egrep 'system_call.*sys_(read|write)' out.perf-folded | ./flamegraph.pl > rw.svg

解决 perf report的后果会更有效率一点;更好的是, perf report能够有一个报表款式 (例如, "- g 折叠"), 间接输入折叠堆栈, 无需stackcollapse-perf.pl。甚至有一个间接输入火焰图SVG的 perf 模式,不过,这将错过可能批改折叠堆栈的价值。

For more details, see my perf_events Flame Graphs page.

DTrace

DTrace 可用于在反对它(Solaris、BSD)的零碎上对 CPU 上堆栈跟踪进行配置文件。上面的示例应用 DTrace 为名为"mysqld"的过程以 99 赫兹对用户级堆栈进行采样,而后生成火焰图(请参阅稍后的 MySQL 示例):

# git clone https://github.com/brendangregg/FlameGraph  # or download it from github# cd FlameGraph# dtrace -x ustackframes=100 -n 'profile-99 /execname == "mysqld" && arg1/ {  @[ustack()] = count(); } tick-60s { exit(0); }' -o out.stacks# ./stackcollapse.pl out.stacks > out.folded# ./flamegraph.pl out.folded > out.svg

两头文件out.folded是没有必要的,因为stackcollapse.pl的输入能够间接通过管道传递给flamegraph.pl。然而,有些状况下,如果想应用vi编辑文件(例如,在采样内核时,要查找和删除闲暇线程)就很不便。

要解释"arg1"查看:arg1 是user-land程序计数器,因而确认它是非零的;arg0 是内核。以下是用于测试内核的 DTrace 命令示例:

# dtrace -x stackframes=100 -n 'profile-199 /arg0/ {    @[stack()] = count(); } tick-60s { exit(0); }' -o out.stacks

这一次,所有线程都进行采样,因而输入将蕴含许多闲暇线程样本(您能够应用 DTrace 筛选它们,也能够应用 grep/vi 筛选折叠的输入)。速率也减少到 199 赫兹,因为捕捉内核堆栈比用户级堆栈便宜得多。奇数编号的速率 99 和 199 用于防止与其余流动统一采样并产生误导性后果。

SystemTap

SystemTap 还能够通过timer.profile 探测器对堆栈跟踪进行采样,该探测器以零碎时钟速率(CONFIG_HZ)。与将示例转储到文件以进行当前聚合和报表的 perf 不同,SystemTap 能够在内核中执行聚合,并把小得多报告传递给user-land。收集的数据和生成的输入能够通过其脚本语言进一步自定义。

在 Fedora 16 上应用 SystemTap v1.7 生成火焰图:

 # stap -s 32 -D MAXBACKTRACE=100 -D MAXSTRINGLEN=4096 -D MAXMAPENTRIES=10240 \   -D MAXACTION=10000 -D STP_OVERLOAD_THRESHOLD=5000000000 --all-modules \   -ve 'global s; probe timer.profile { s[backtrace()] <<< 1; }    probe end { foreach (i in s+) { print_stack(i);   printf("\t%d\n", @count(s[i])); } } probe timer.s(60) { exit(); }' \   > out.stap-stacks # ./stackcollapse-stap.pl out.stap-stacks > out.stap-folded # cat out.stap-folded | ./flamegraph.pl > stap-kernel.svg

下面应用了六个选项 (-s 32,-D...) 减少了各种SystemTap限度。火焰图惟一真正须要的是"-D MAXBACKTRACE=100 -D MAXSTRINGLEN=4096",这样堆栈轨迹不会截断;在忙碌工作负载上长时间采样(本例中为 60 秒)时,须要其余采样,以防止各种阈值和溢出谬误。

应用timer.profile 探针,以 100 赫兹对所有 CPU 进行采样:有点毛糙,并冒着lockstep采样的危险。上次我查看时,计时器.hz(997) 探头以正确的速率发射,但无奈读取堆栈回溯。

ktap

ktap 曾经通过 ktap 的scripts/profiling/stack_profile.kp 脚本反对 CPU 火焰图,该脚本捕捉示例数据。上面是应用 ktap one-liner而不是该脚本的步骤:

# ktap -e 's = ptable(); profile-1ms { s[backtrace(12, -1)] <<< 1 }  trace_end { for (k, v in pairs(s)) { print(k, count(v), "\n") } }  tick-30s { exit(0) }' -o out.kstacks# sed 's/    //g' out.kstacks | stackcollapse.pl > out.kstacks.folded# ./flamegraph.pl out.kstacks.folded > out.kstacks.svg

sed(1) 命令删除制表符(这是制表符,而不是一系列空格),stackcollapse.pl解决文本。一stackcollapse-ktap.pl能够轻松地编写到间接解决 ktap 输入,并防止对 sed(1) 的须要。

This full example is on my ktap page under ktap Flame Graphs.

Other Profilers

无关其余探查器,请参阅Flame Graphs主页上的更新链接。其中包含戴夫·帕切科的node.js functions,马克·普罗布斯特的OS X上的Flame Graphs for Instruments,以及布鲁斯·道森在微软Windows上的Summarizing Xperf CPU Usage with Flame Graphs。

  1. Examples

下一个示例应用 DTrace 剖析 MySQL,而后应用 DTrace 剖析 Linux 内核的两个 CPU perf_events。这些是不反对单击缩放的旧示例(您依然能够按鼠标悬停查看详细信息)。

Linux 示例是在 KVM (Ubuntu 主机) 下运行的 3.2.9 (Fedora 16 来宾) 上生成的,并配有一个虚构 CPU。某些代码门路和采样比率在裸机上会大不相同:例如,网络不会通过 virtio-net 驱动程序进行解决。

MySQL

这是导致我创立火焰图的原始性能问题。这是一个生产 MySQL 数据库, 耗费的 CPU 比心愿的要多。可用的探查器是 DTrace, 我应用它频率计数 CPU 用户级堆栈:

# dtrace -x ustackframes=100 -n 'profile-997 /execname == "mysqld"/ {    @[ustack()] = count(); } tick-60s { exit(0); }'dtrace: description 'profile-997 ' matched 2 probesCPU     ID                    FUNCTION:NAME  1  75195                        :tick-60s [...]              libc.so.1`__priocntlset+0xa              libc.so.1`getparam+0x83              libc.so.1`pthread_getschedparam+0x3c              libc.so.1`pthread_setschedprio+0x1f              mysqld`_Z16dispatch_command19enum_server_commandP3THDPcj+0x9ab              mysqld`_Z10do_commandP3THD+0x198              mysqld`handle_one_connection+0x1a6              libc.so.1`_thrp_setup+0x8d              libc.so.1`_lwp_start             4884              mysqld`_Z13add_to_statusP17system_status_varS0_+0x47              mysqld`_Z22calc_sum_of_all_statusP17system_status_var+0x67              mysqld`_Z16dispatch_command19enum_server_commandP3THDPcj+0x1222              mysqld`_Z10do_commandP3THD+0x198              mysqld`handle_one_connection+0x1a6              libc.so.1`_thrp_setup+0x8d              libc.so.1`_lwp_start             5530

此处显示了最初两个最常见的堆栈。最初一次是在 CPU 上采样 5,530 次,看起来是 MySQL 在做一些零碎状态内务治理。如果这是最热的, 咱们晓得咱们有一个 Cpu 问题, 兴许我应该去寻找可调性来禁用零碎统计数据。

问题是,大部分输入都从此屏幕截图中截断("[...]"),并且(与 Linux perf 不同),DTrace 不打印百分比,因而您不确定这些堆栈真正重要多少。我依据样本总数(即 348,427)手动计算百分比,后果令我丧气的是,这两个堆栈仅代表不到 3% 的 CPU 样本。

雷同的 MySQL 配置文件数据,出现为火焰图:

您能够对元素进行鼠标悬停以查看百分比(但无奈单击缩放,因为这是旧版本),显示剖析数据中元素的频繁存在。您还能够独自查看 SVG 或 PNG 版本。

较早截断的文本输入将 MySQL 状态堆栈标识为最热。火焰图显示了事实:大多数时候真的是在JOIN::exec。这指出了考察的方向:JOIN::exec,以及下面的性能,并导致问题失去解决。

File Systems

作为不同工作负载的示例,这显示了在存档 ext4 文件系统时 Linux 内核 CPU 工夫(SVG, PNG):

这显示了文件系统的读取以及内核 CPU 工夫破费的工夫。大多数内核工夫是在 sys_newfstatat() 和 sys_getdents(): 元数据工作作为文件系统的步行。sys_openat() 在右侧,因为关上文件要读取,而后是 mmap()d(查看 sys_getdents(),这些是按字母顺序排列的),最初页面有故障进入用户空间(请参阅左侧的 page_fault() )。

而后,挪动字节的理论工作将用user-land中的 mmap'd 段的上(内核火焰图中未显示)。如果归档程序应用 read() 零碎调用代替,此火焰图将看起来十分不同,并且具备较大的 sys_read() 组件。

Short Lived Processes

对于此火焰图,我执行了短期过程工作负载,以查看内核工夫在创立中破费的工夫(SVG, PNG):

除了性能剖析之外,这也是学习Linux内核外部性能的一个很好的工具。

User+Kernel Flame Graph

此示例显示 illumos 内核虚拟机管理程序主机上的用户和内核堆栈(SVG, PNG) :

您还能够查看独立的 SVG和 PNG 版本。这显示了 qemu 线程 3 的 CPU 应用状况,即 KVM 虚构 CPU。包含用户和内核堆栈(DTrace 能够同时拜访这两个堆栈),零碎调用介于黑白灰色之间。

零碎(vcpu_enter_guest)是该虚构 CPU 在虚拟机内执行代码的中央。我更感兴趣的是左边的山,来查看KVM进口代码门路的性能。

  1. C

易于剖析,请参阅步骤阐明Instructions。一个陷阱是,许多编译器(包含 gcc)不将帧指针寄存器作为编译器优化,这突破了基于帧指针的堆栈步走。这通常产生在通过 Linux 存储库装置的软件中,并且您的火焰图将失落塔。修复程序包含:

  • Recompile with -fno-omit-frame-pointer.
  • On Linux: install debuginfo for the software with DWARF data and use perf's DWARF stack walker.
  1. C++

易于剖析,但可能会因为与 C 雷同的起因而蒙受堆栈跟踪损坏:请参阅profiling C局部。

  1. Java

我的 JavaOne 2016 应用火焰图在 Linux 上探讨 Java 性能剖析,总结了应用 Linux perf 生成混合模式火焰图的最新技术。

Background

为了生成火焰图,您须要一个能够采样堆栈轨迹的探查器。历史上有两种类型的探查器:

  1. System profilers: like Linux perf, which shows system code paths (eg, JVM GC, syscalls, TCP), but not Java methods.
  2. JVM profilers: like hprof, LJP, and commercial profilers. These show Java methods, but usually not system code paths.

能够应用 (1) 执行火焰图,具体方法如前所述。(2) 取决于要应用的探查器。火焰图软件包含stackcollapse-ljp.pl,用于解决Lightweight Java Profiler (LJP)的输入。我的博客文章Java Flame Graphs总结了如何应用 LJP。如果创立零碎火焰图(例如,在 Linux 上应用 perf)以及 LJP 火焰图,通常能够通过查看两者来解决所有问题。

现实状况下,咱们有一个火焰图能够实现这所有:零碎和Java代码门路。除了不便之外,它还在Java上下文中显示零碎代码门路,这对正确理解配置文件至关重要。

问题是让零碎探查器理解 Java 办法和堆栈跟踪。例如,如果您应用Linux的perf_events ,你会看到十六进制数字和断开的堆栈跟踪,因为它无奈将地址转换为 Java 符号,并且无奈跟踪 JVM 堆栈。DTrace 长期以来始终反对 jstack() 操作,但该操作也有问题,稍后将介绍。

有两个具体问题:

  1. The JVM compiles methods on the fly (just-in-time: JIT), and doesn't expose a traditional symbol table for system profilers to read.
  2. The JVM also uses the frame pointer register (RBP on x86-64) as a general purpose register, breaking traditional stack walking.

Linux perf_events

解决上述两个问题的一种办法:

  1. A JVMTI agent, perf-map-agent (previously here), which can provide a Java symbol table for perf to read (/tmp/perf-PID.map).
  2. The -XX:+PreserveFramePointer JVM option, so that perf can walk frame pointer-based stacks.

将 PreserveFramePointer 增加到 JDK8u60 中,以不便 perf 和火焰图生成(我通过电子邮件发送了一个原型到热点编译器开发人员邮件列表,[A hotspot patch for stack profiling (frame pointer),该修补程序成为 JDK-8068945: Use RBP register as proper frame pointer in JIT compiled code on x64。我在 Netflix Tech 博客上总结了最初一步: Java in Flames。以下是更新的步骤:

  1. install perf-map-agent:

    sudo bash
    apt-get install cmake
    export JAVA_HOME=/path-to-your-new-jdk8
    cd /destination-for-perf-map-agent # I use /usr/lib/jvm
    git clone --depth=1 https://github.com/jvm-profil...
    erf-map-agent
    cmake .
    make

  2. profiling and flame graph generation:

    git clone --depth=1 https://github.com/brendangre...
    sudo bash
    perf record -F 49 -a -g -- sleep 30; ./FlameGraph/jmaps
    perf script > out.stacks01
    cat out.stacks01 | ./FlameGraph/stackcollapse-perf.pl | grep -v cpu_idle | \
    /FlameGraph/flamegraph.pl --color=java --hash > out.stacks01.sv

请留神,jmap(调用 perf 映射代理执行符号转储的帮忙程序脚本)要在 perf 记录后立刻运行,以最大限度地缩小符号改变。

产生火焰图的示例是 (SVG, 反对点击缩放):

运行flamegraph.pl应用 --color=java,它应用不同的帧类型应用不同的色调。绿色为 Java,黄色C++,橙色为内核,红色为残余(本机用户级别或内核模块)。

这是目前的概念证实,并且不反对该修补程序。无关探讨和状态,请参阅邮件列表,以及无关此办法的注意事项。返回帧指针的确会破费一些性能(取决于工作负载,可能能够忽略不计),并且火焰图不显示内线办法。我心愿修补程序作为可调选项蕴含在内,例如 -XX:NoOmitFramePointer。

DTrace

DTrace 应用 jstack() 操作能够剖析用户级堆栈以及 Java 办法和类。(In theory: see the bugs listed below.)它应用的性能称为"DTrace ustack helper"(搜寻该术语以理解无关它们理解更多信息)。因而,要为 Java 程序生成 CPU 火焰图,能够应用以下办法收集堆栈:

# dtrace -n 'profile-97 /execname == "java"/ { @[jstack(100, 8000)] = count(); }    tick-30s { exit(0); }' -o out.javastacks_01

而后,能够将输入文件stackcollapse.pl和 flamegraph.pl,如后面各节所示。

ustack 帮忙器操作是 jstack(),如果工作,您将有看起来像这样的堆栈:

libjvm.so`jni_GetObjectField+0x10flibnet.so`Java_java_net_PlainSocketImpl_socketAvailable+0x39java/net/PlainSocketImpl.socketAvailable()I*java/net/PlainSocketImpl.available()I*java/lang/Thread.run()V0xfb60035elibjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHa...libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmeth...libjvm.so`__1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_n...libjvm.so`__1cMthread_entry6FpnKJavaThread_pnGThread__v_+0x113libjvm.so`__1cKJavaThreadDrun6M_v_+0x2c6libjvm.so`java_start+0x1f2libc.so.1`_thrp_setup+0x88libc.so.1`_lwp_start  9

请留神,它包含libjvm帧和类/办法:java/net/PlainSocketImpl.available()等。如果没有可见的类/办法,只有十六进制数字,则须要让 jstack() 先工作。

可怜的是,这个办法有多个问题。首先,jstack() 在许多 JVM 版本中都不起作用。无关列表,请参阅bug JDK-7187999。侥幸的是,第一个问题有解决办法,在Adam's email和 illumos issue 3123 中形容,最终的用法(自从他最后的倡议以来已更改)波及在启动 Java 程序时设置一个环境变量,以确保加载 ustack 帮忙程序。例如:

illumos# LD_AUDIT_32=/usr/lib/dtrace/libdtrace_forceload.so java myprog

请留神,这可能会减少超过 60 秒的启动工夫。(这自身须要性能剖析。)

将生成的火焰图视为 SVG 或 PNG。工作负载是 ttcp(测试 TCP),这是用 Java 编写的 TCP 基准。火焰图显示,大多数 CPU 工夫都花在套接字写入()中,9.2% 的工夫用于 releaseFD()。

第二个问题,jstack() 可能无奈正确走堆栈,因为谬误 JDK-6276264,在 2005 年提交,截至 2014 年未修复。对于我的生产工作负载,简直所有采样堆栈都因为此 Bug 而损坏。jstack() 无奈应用。

  1. Node.js

v8 与 Java 有相似的问题。现实状况下,咱们心愿应用一些探查器来采样系统代码门路和 v8 JavaScript 代码门路。

Linux perf_events

应用perf_events(v8选项 --perf_basic_prof或perf_basic_prof_only_functions)能够剖析JavaScript堆栈。请参阅我的博客Node Flame Graphs on Linux。还有特雷弗·诺里斯的原始阐明instructions,还有他的example。

Here is an example Linux perf CPU flame graph (SVG):


这应用 --color=js 应用不同的色调:green == JS, aqua == built-ins, yellow == C++, red == system(本机用户级别和内核)。

My example here is little more than hello world, so there's very little JavaScript (green frames) to be seen. Here's a more interesting example.

DTrace

与 Java 一样,DTrace 采纳不同的办法,应用"ustack helper"。见戴夫·帕切科的post,在那里他也演示火焰图。

  1. Other Languages

请参阅Flame Graphs Updates局部,并搜寻您感兴趣的语言。

  1. Other Uses

火焰图可视化实用于任何堆栈跟踪和值组合,而不仅仅是重叠具备 CPU 样本计数的跟踪,如上述值。例如,您能够跟踪设施 I/O、零碎调用、CPU 外事件、特定函数调用和内存调配。对于其中任何一个,能够收集堆栈跟踪以及相干值:计数、字节或提早。请参阅Flame Graphs页面上的其余类型的类型。

  1. Background & Acknowledgements

我出于必要而创立此可视化成果:我从各种不同的性能问题中提供了大量堆栈示例数据,须要疾速开掘这些数据。我首先尝试创立一些基于文本的工具来汇总数据,但收效甚微。而后,我想起了Neelakanth Nadgir(另一个Roch Bourbonnais创立了并给我看)创立的定时可视化成果,并认为堆栈示例能够以相似的形式出现。Neel 的可视化成果看起来很棒,但跟踪每个函数条目和返回我的工作负载的过程对性能的影响太大。在我的状况下,更重要的是要有精确的百分比来量化代码门路,而不是工夫排序。这意味着我能够对堆栈(低开销)进行采样,而不是跟踪函数(高开销)。

第一个可视化工作,并立刻确定了 KVM 代码的性能改良(一些增加的性能比预期的老本更高)。从那以后,我屡次应用它进行内核和应用程序剖析,其他人也始终在宽泛的指标上应用它,包含节点.js剖析。狩猎高兴!

  1. References

  • The Flame Graph page, and github repo
  • Linux perf_events wiki
  • The Unofficial Linux Perf Events Web-Page
  • The SystemTap homepage
  • My Linux Performance Checklist, which includes perf_events, SystemTap and other tools

See the Flame Graph: Updates section for other articles, examples, and instructions for using flame graphs on many other targets, including Ruby, OS X, Lua, Erlang, node.js, and Oracle.