跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
Shell / Bash

Linux CPU 性能分析工具:火焰图 (Flame Graphs) 详解

综述由AI生成火焰图是一种可视化 CPU 性能剖析的工具,通过展示函数调用栈帮助定位性能瓶颈。文章阐述了火焰图的基本原理、坐标轴含义及交互功能,演示了如何使用 stackcount 和 profile 工具收集调用栈数据,并结合 FlameGraph 脚本生成 SVG 图像。内容包含内核函数采样与全局采样的具体命令示例,以及如何通过火焰图分析系统负载和 CPU 使用效率。

DataScient发布于 2025/1/20更新于 2026/4/243 浏览
Linux CPU 性能分析工具:火焰图 (Flame Graphs) 详解

火焰图是什么?

火焰图(Flame Graph)是一种可视化工具,可用于 CPU 性能剖析,可视化 CPU 中函数执行调用栈,以及来自任何剖析器或跟踪器所记录的调用栈信息。它由 Brendan Gregg 发明,并广泛用于性能分析和优化领域。

下图为一台部署了 OpenStack 环境的机器,作为 master 节点存在,运行命令 profile -af 30 > out.stacks01 生成的调用栈数据的火焰图可视化展示。

Linux CPU 性能分析工具火焰图

我们上面讲到了调用栈,对应没接触编码的小伙伴可能不太熟悉,那么调用栈又是什么?

调用栈信息

调用栈信息,也称为栈回溯跟踪或调用跟踪信息,是一串展示了代码流向的函数名字。例如,如果 func_a() 调用了 func_b(),后者又调用了 func_c(),那么那里的调用栈信息可以写成:

func_c func_b func_a 

栈的底部 (func_a) 是起点,它之上的行显示了代码流向。换句话说,栈的顶部 (func_c) 是当前函数,向下移动则显示了它的派生关系:先是父亲函数,然后是祖父函数,依此类推。

实际的函数关系可能是这样

func_a(){ func_b(); } func_b(){ func_c(); } func_c(){ print("当前执行到这里啦") }
为什么需要火焰图对调用栈进行剖析

以定时采样方式收集调用栈信息,一般会收集数千个调用栈信息,每个调用都有几十或几百行那么长。为了使这样体量的数据易于分析:

  • Linux 的 perf(1) 剖析器将其样本摘要为调用树格式,显示每个分支所占的百分比。
  • BCC 的 profile(8) 工具则采用了另外一种摘要方式:对每个独特的调用栈分别计数。

使用这两种工具时,如果有某个调用栈占用大量 CPU 运行时间,那么此类问题可以很快被识别出来。不过对于许多其他分析场景,包括一些微小的性能回归测试 (进行更改后是否出现性能下降),定位罪魁祸首可能需要研究数百页的剖析器输出。火焰图就是为了解决这个问题。

火焰图怎么看?

下述输出显示了一个调用栈和对应的累计数,总计 10 个样本。举例来说

func_e func_d func_b func_a 1 func_b func_a 2 func_c func_b func_a 7 

func_a()->func_b()->func_c() 这个代码路径有 7 次采样。这个代码路径显示了 fun_c() 正在 CPU 上运行。而 func_a()->unc_b() 这个代码路径,即 func_b() 正在 CPU 上运行,被采样了 2 次。然后一个以 func_e() 结束的调用栈被采样了 1 次。

对应的火焰图

Linux CPU 性能分析工具火焰图

火焰图具备以下特点:

  • 每个方块代表了调用栈中的一个函数 (一个'栈帧')。
  • Y 轴:显示了栈的深度 (栈中帧的数量),顺序是底部代表根,顶部代表叶子。从下往上看时,展示的是代码执行的方向;从上往下看时,则看到的是函数的调用层次关系。
  • X 轴:包括了全部的采样样本的数量。要注意的一点是,和一般的图不同,火焰图从左到右并不代表时间流动的方向。火焰图从左到右只是按照字母顺序排列,目的是将位于栈中同一层的函数最大化地合并。和轴的函数栈帧一起看,图的原点在左下方 (和一般的图一样),表示 [0,a] 区间。
  • X 轴上方块的长度确实也有它的意义:方块的长度表示了该函数在剖析文件中出现次数的比重。较长的方块所对应的函数比较短的方块所对应的函数在采样样本中出现的次数多。
功能性操作

鼠标悬浮特性

原始的火焰图软件生成的 SVG 文件内置了 JavaScript,可以被加载到浏览器中,用于实现实时交互。其中的一个特性是,当鼠标指针移动到相应的栈帧上时,会有一行信息显示出来,表明该栈帧在整个剖析文件中所占的比例。

缩放

可以单击栈帧实现横向缩放。这可将较窄的栈帧展开放大,这样就能看到它们的名字。类似一个数据可视化中下转操作。

搜索

使用搜索按钮,或者按 Ctrl+F 组合键,允许输入搜索关键词,命中的会以洋红色高亮显示出来,同时显示搜索命中结果在所有堆栈中所占的百分比。这就使得计算特定代码区域在整个文件中所占的比例十分容易。

如何生成火焰图?

当前实验环境

[root@localhost ~]# hostnamectl Static hostname: vms99.liruilongs.github.io Icon name: computer-vm Chassis: vm Machine ID: ea70bf6266cb413c84266d4153276342 Boot ID: e09f7f3829ca4df1bea57385262eb16b Virtualization: vmware Operating System: Rocky Linux 8.9 (Green Obsidian) CPE OS Name: cpe:/o:rocky:rocky:8:GA Kernel: Linux 4.18.0-513.9.1.el8_9.x86_64 Architecture: x86-64
某一内核函数调用采样

stackcount 工具是一个 BPF 工具,用于通过给定频率对函数的内核堆栈进行计数。这是在内核中使用 eBPF 映射来实现的。只有唯一的堆栈和它们的计数被复制到用户级进行打印。

[root@localhost ~]# stackcount -f -P -D 10 ktime_get > out.txt

上面的命令的意思:

  • -f、–folded:输出折叠格式
  • -P、–perpid:对每个进程分别显示栈信息
  • -D DURATION、–duration DURATION:总共跟踪的秒数
  • ktime_get: 调用函数 (Linux 内核空间的系统调用,获取时钟时间)
[root@localhost ~]# ls anaconda-ks.cfg date.log output.txt out.txt set.sh SHA256SUMS
[root@localhost ~]# wc out.txt 220 440 53978 out.txt

生成对应的堆栈数据之后需要通过工具 (FlameGraph) 转化为火焰图

项目地址:

克隆项目

[root@localhost ~]# git clone https://github.com/brendangregg/FlameGraph.git
正克隆到 'FlameGraph'...
remote: Enumerating objects: 1285, done.
remote: Counting objects: 100% (707/707), done.
remote: Compressing objects: 100% (146/146), done.
remote: Total 1285 (delta 584), reused: 575 (delta 561), pack-reused: 578
接收对象中:100% (1285/1285), 1.92 MiB | 174.00 KiB/s, 完成.
处理 delta 中:100% (761/761), 完成.
[root@localhost ~]# cd FlameGraph/

通过下面的命令生成对应的火焰图矢量图

[root@localhost ~/FlameGraph]# ./flamegraph.pl --hash --bgcolors=grey < ../out.txt > out.svg
Can't locate open.pm in @INC (you may need to install the open module) (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5) at ./flamegraph.pl line 97.
BEGIN failed--compilation aborted at ./flamegraph.pl line 97.

可以看到报错了,这个错误消息表明在运行 ./flamegraph.pl 脚本时,Perl 解释器无法找到所需的 open.pm 模块。该模块可能没有正确安装或没有包含在 Perl 解释器的模块搜索路径中。

要解决这个问题,你可以尝试以下几个步骤:

检查模块安装:确保 open.pm 模块已经正确安装。你可以使用 CPAN 或其他 Perl 模块管理工具来安装该模块。

安装模块管理器

[root@localhost ~/FlameGraph]# yum install perl-CPAN -y

安装模块

[root@localhost ~/FlameGraph]# cpan open
Loading internal null logger. Install Log::Log4perl for logging messages
CPAN.pm requires configuration, but most of it can be done automatically.
If you answer 'no' below, you will enter an interactive dialog for each configuration option instead.
Would you like to configure as much as possible automatically? [yes] yes
CPAN: HTTP::Tiny loaded ok (v0.074)
...............
http://www.cpan.org/modules/03modlist.data.gz
Reading '/root/.cpan/sources/modules/03modlist.data.gz'
DONE
Writing /root/.cpan/Metadata
Running install for module 'open'
The most recent version "1.13" of the module "open" is part of the perl-5.38.2 distribution.
To install that, you need to run force install open --or-- install P/PE/PEVANS/perl-5.38.2.tar.gz

安装完之后提示我们需要安装对应的 perl 版本

[root@localhost ~/FlameGraph]# perl -v This is perl 5, version 26, subversion 3 (v5.26.3) built for x86_64-linux-thread-multi (with 58 registered patches, see perl -V for more detail)
Copyright 1987-2018, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on this system using "man perl" or "perldoc perl".
If you have access to the Internet, point your browser at http://www.perl.org/, the Perl Home Page.
[root@localhost ~/FlameGraph]# yum -y install perl -y

升级 perl 版本之后,火焰图可以正常生成

[root@localhost ~/FlameGraph]# ./flamegraph.pl --hash --bgcolors=grey < ../out.txt > out.svg
[root@localhost ~/FlameGraph]#

下面为生成到的火焰图

Linux CPU 性能分析工具火焰图

可以看到最下层为 swapper 调用系统时间函数对应每个 VCPU,当前系统为 6 核,都是 swapper 的调用

说明系统整体 CPU 利用率很低,大部分时间都在执行 swapper 代表的 idle 等待状态。

[root@localhost ~]# top
 top - 17:56:14 up 1 day, 10:11, 2 users, load average: 0.00, 0.00, 0.00
Tasks: 243 total, 1 running, 242 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu4 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu5 : 0.0 us, 1.0 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 6141.5 total, 4655.9 free, 405.9 used, 1079.7 buff/cache
MiB Swap: 2068.0 total, 2068.0 free, 0.0 used.
5465.6 avail Mem

Linux CPU 性能分析工具火焰图

单击其中一个核的调用,可以查看详细调用信息,更深的颜色代表占用时间更长的函数。更浅的颜色代表占用时间较短的函数。

Linux CPU 性能分析工具火焰图

swapper 任务没有实质工作,它实际代表的就是 CPU 等待工作或空闲的时间。通过统计其 CPU 时间可以评估系统负载和 CPU 使用效率。它起到了监控和统计 CPU 的作用。

全局的采样

profile(8) 是一个定时采样调用栈信息并且汇报调用栈出现频率信息的 BCC 工具。该工具可以同时记录几乎所有占用 CPU 的代码调用栈。该工具的额外消耗几乎可以忽略不计,因为该工具是定时采样,采样频率可以随时调整。

默认情况下,该工具以 49Hz 的频率同时采样所有 CPU 的用户态和内核态的调用栈

下面的命令将 30 秒的采样信息输出到 out.stacks01 文件中,并且在输出中标记内核函数 (a),-f 以折叠的方式

[root@localhost ~]# profile -af 30 > out.stacks01

生成对应的火焰图

[root@localhost ~]# cd FlameGraph/
[root@localhost ~/FlameGraph]# ./flamegraph.pl < ../out.stacks01 > outs.svg

指定时间的所以的调用栈信息

Linux CPU 性能分析工具火焰图

查看 haproxy 相关的调用栈信息

Linux CPU 性能分析工具火焰图

查看容器运行时相关的调用栈信息

Linux CPU 性能分析工具火焰图

目录

  1. 火焰图是什么?
  2. 调用栈信息
  3. 为什么需要火焰图对调用栈进行剖析
  4. 火焰图怎么看?
  5. 功能性操作
  6. 如何生成火焰图?
  7. 某一内核函数调用采样
  8. 全局的采样
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Java 随机数生成器全方位对比
  • 基于 Claude MCP 协议的智能体落地示例
  • 缓存算法:LRU 与 LFU 原理及 Java 实现
  • DeepSeek-R1-Distill-Llama-70B:开源推理效率分析
  • 前端拖拽排序实现详解:从原理到实践
  • 基于SSM和Vue的Web在线投稿系统设计与实现
  • 恩智浦发布S32N7处理器系列,加速AI驱动汽车发展
  • MAVROS 安装与基础知识梳理及 ROS C++ 仿真案例
  • DCU BW1000 环境下 llama.cpp 推理 Qwen3-Coder 模型问题排查
  • 基于火山引擎即梦 API 的数字人视频生成 Streamlit Demo
  • Java Web 开发环境搭建:IDEA 与 Tomcat 安装部署指南
  • 使用 AI 生成 SEEDVR2 虚拟现实项目代码
  • 数据结构:二叉树经典习题讲解
  • GitHub Copilot 接入第三方 OpenAI 接口无需扩展
  • Retinaface+CurricularFace 轻量级 CPU 人脸识别部署方案
  • STL 底层解析:map 与 set 基于红黑树的封装及迭代器实现
  • VS Code GitHub Copilot 账号切换与退出指南
  • 智谱开源 7440 亿参数智能体模型 GLM-5
  • 剑指 Offer 第 2 版:链表算法详解
  • 字节跳动音视频前端一面面经与深度解析

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online