当前位置: 首页 > news >正文

使用 `perf` 和火焰图(Flame Graph)进行性能分析

在现代软件开发中,性能优化是提升应用程序响应速度和资源利用率的关键步骤。当一个进程的 CPU 占用率异常高时,识别并优化性能瓶颈显得尤为重要。本文将详细介绍如何使用 Linux 下强大的性能分析工具 perf 以及火焰图(Flame Graph)来分析和优化高 CPU 占用的进程。

目录

  1. 前言
  2. 使用 perf 收集性能数据
    • 安装 perf
    • 收集数据
  3. 使用 perf report 分析数据
    • 基本使用
    • 界面导航与操作
    • 过滤与搜索
  4. 生成火焰图(Flame Graph)
    • 安装 FlameGraph 工具
    • 生成火焰图
    • 分析火焰图
  5. 优化与验证
  6. 实用技巧与常见问题
  7. 总结

前言

perf 是 Linux 内核提供的一个功能强大的性能分析工具,能够监控和分析系统及应用程序的性能瓶颈。通过 perf,开发者可以深入了解程序在运行过程中各个函数的执行情况,从而找到高 CPU 占用的根本原因。

火焰图(Flame Graph)则是一种可视化性能数据的工具,能够直观地展示函数调用的层级关系及其耗时情况。结合 perf 和火焰图,开发者可以更高效地进行性能分析和优化。

使用 perf 收集性能数据

安装 perf

在大多数 Linux 发行版中,perf 作为内核工具包的一部分,可以通过包管理器进行安装。例如,在 Ubuntu 上:

sudo apt-get update
sudo apt-get install linux-tools-common linux-tools-generic linux-tools-$(uname -r)

说明:

  • linux-tools-commonlinux-tools-genericperf 工具所需的基础包。
  • linux-tools-$(uname -r) 确保安装与当前内核版本匹配的 perf 版本。

收集数据

使用 perf record 命令来采样和记录目标进程的性能数据。假设目标进程的 PID 为 252698,运行以下命令:

sudo perf record -p 252698 -F 99 --call-graph dwarf -o perf.data

参数说明:

  • -p 252698:指定要监控的进程 PID。
  • -F 99:设置采样频率为 99 Hz。
  • --call-graph dwarf:收集调用图,便于分析函数调用关系。
  • -o perf.data:指定输出文件为 perf.data

使用 perf report 分析数据

收集完性能数据后,使用 perf report 命令进行分析。

基本使用

sudo perf report -i perf.data
  • -i perf.data:指定输入文件为之前采集的 perf.data

执行上述命令后,将启动一个交互式的命令行界面,展示性能分析结果。

界面导航与操作

perf report 的交互界面主要包括以下部分:

  1. 标头信息(Header):显示基本信息,如采样总数、监控的事件类型(如 CPU cycles)、进程名称等。
  2. 汇总视图(Summary View):列出占用 CPU 最多的函数或模块,每行通常包含:
    • Overhead (%):该函数消耗的 CPU 百分比。
    • Shared Object:函数所属的共享库或可执行文件。
    • Symbol:函数名或符号名称。
  3. 函数调用详情(Function Call Details):选择某个函数后,深入查看其调用关系。

常用快捷键:

  • 上下箭头:在函数列表中移动光标。
  • 回车 (Enter):展开或进入选中的函数,查看详细的调用关系。
  • 左右箭头:折叠或展开调用树。
  • ?:查看帮助,了解更多快捷键和操作说明。
  • q:退出 perf report

过滤与搜索

为了更快地定位问题,可以使用过滤和搜索功能。

过滤

按下 / 键进行过滤,输入关键词(如函数名或模块名),例如:

/compute

这将只显示包含 “compute” 的函数。

搜索

按下 s 键可以搜索特定的符号或函数名称,输入后按回车即可高亮显示。

导出报告

如果需要将报告导出为文本文件,可以使用以下命令:

sudo perf report -i perf.data --stdio > perf_report.txt

此命令将报告以纯文本形式输出到 perf_report.txt 文件中,便于后续查看或分享。

生成火焰图(Flame Graph)

火焰图是一种直观展示函数调用层级及耗时的可视化工具。通过结合 perf 和火焰图,开发者可以更清晰地识别性能瓶颈。

安装 FlameGraph 工具

首先,需要安装由 Brendan Gregg 提供的 FlameGraph 工具:

git clone https://github.com/brendangregg/FlameGraph.git

生成火焰图

以下是生成火焰图的步骤:

  1. 导出 perf 事件数据:

    sudo perf script -i perf.data > out.perf
    
  2. 生成折叠的堆栈数据:

    ./FlameGraph/stackcollapse-perf.pl out.perf > out.folded
    
  3. 生成火焰图 SVG 文件:

    ./FlameGraph/flamegraph.pl out.folded > flamegraph.svg
    
  4. 查看火焰图:

    使用浏览器打开 flamegraph.svg 文件,直观地查看火焰图。

分析火焰图

火焰图的每个“火焰”代表一个函数调用,宽度表示该函数消耗的 CPU 时间。堆叠的层级展示了函数调用的层级关系。通过分析火焰图,可以识别出哪些函数或调用链消耗了大量的 CPU 资源。

示例分析:

假设火焰图中,compute_heavy_task 宽度较大,表示其占用了大量 CPU 时间。深入查看该函数的调用栈,可以发现其调用了 helper_function1calculate,进一步优化这些子函数可能会显著降低整体 CPU 占用率。

优化与验证

在识别出性能瓶颈后,进行针对性的代码优化:

  1. 优化算法:改进耗时的算法,减少计算复杂度。
  2. 减少不必要的计算:避免重复计算或不必要的资源消耗。
  3. 提高并行度:利用多线程或并行计算,提高资源利用率。
  4. 缓存优化:优化内存访问,提高缓存命中率。

优化完成后,重复上述 perf 和火焰图的分析步骤,验证优化效果是否显著,确保 CPU 占用率得到有效降低。

实用技巧与常见问题

保持调试信息

为了确保 perf 能准确解析函数名和源代码位置,编译应用程序时应包含调试信息。例如,使用 gcc 编译时添加 -g 选项:

gcc -g -o myapp myapp.c

处理容器化环境中的符号问题

当在容器中运行应用程序时,perf 可能无法正确解析容器内部的符号,导致“Unregistered symbol…”错误。解决方法如下:

  1. 确定容器的 rootfs 路径

    • Device Mapper 类型
      docker inspect --format='{{.GraphDriver.Data.MergedDir}}' <container_id>
      
    • Overlay 类型
      使用 docker export 命令导出容器的 rootfs:
      docker export <container_id> -o container_rootfs.tar
      mkdir container_rootfs
      tar -xf container_rootfs.tar -C container_rootfs
      
    • 富容器(如 Podman 等)
      直接使用外置的 rootfs 路径。
  2. 使用 --symfs 参数指定 rootfs 路径

    sudo perf record --symfs /path/to/container/rootfs -p 252698 -F 99 --call-graph dwarf -o perf.data
    sudo perf script --symfs /path/to/container/rootfs -i perf.data > out.perf
    
  3. 继续生成火焰图

    ./FlameGraph/stackcollapse-perf.pl out.perf > out.folded
    ./FlameGraph/flamegraph.pl out.folded > flamegraph.svg
    

通过上述步骤,perf 能正确解析容器内部的符号,生成准确的火焰图。

多核处理

在多核心系统上,perf 会自动采样所有 CPU 核心的数据。如果需要针对特定的 CPU 核心进行分析,可以使用 -C 选项指定核心编号:

sudo perf record -C 0 -p 252698 -F 99 --call-graph dwarf -o perf.data

这将仅监控 CPU 核心 0 上的性能数据。

性能开销

虽然 perf 是轻量级的性能分析工具,但在高频率采样或长时间运行时,仍可能对系统性能产生一定影响。建议在测试环境或非高峰时段进行分析。

持续监控与自动化

对于需要持续监控的应用,可以编写脚本定期运行 perf 采样并生成报告,结合 cron 定时任务和报警机制,实现自动化性能监控。

总结

使用 perf 收集和分析高 CPU 占用进程的性能数据,并结合火焰图进行直观的可视化分析。通过识别热点函数和调用关系,针对性地进行代码优化,可以显著提升应用程序的性能表现。

工作流程总结:

  1. 收集性能数据:使用 perf record 监控目标进程,生成 perf.data
  2. 分析数据:使用 perf report 查看热点函数和调用关系。
  3. 生成火焰图:通过 perf script 和 FlameGraph 工具生成火焰图,直观分析。
  4. 优化代码:根据分析结果优化代码,降低 CPU 占用。
  5. 验证效果:重新进行性能分析,确认优化效果。

通过不断迭代这一过程,您可以逐步优化应用程序,提升其性能和稳定性。

http://www.xdnf.cn/news/465283.html

相关文章:

  • 25.5.15
  • MySQL读写分离
  • 深入解析C++模板:从基础到高级应用
  • LeetCode 热题 100 437. 路径总和 III
  • 运维职业发展思维导图
  • 建筑兔零基础人工智能自学记录92|类脑智能与脑机接口-7
  • vue3搭建脚手架前的前置知识
  • 【Unity】给出两个旋转角度,判断是应该左转还是右转
  • QT设置MySQL驱动
  • 已解决(亲测有效!):安装部署Docker Deskpot之后启动出现Docker Engine Stopped!
  • 11 web 自动化之 DDT 数据驱动详解
  • 文件目录与检索综合练习题
  • 面试 Linux 运维相关问题
  • 基于SpringBoot的家政服务系统设计与实现(源码+文档+部署讲解)
  • 20、鸿蒙学习——OAID、AAID、ODID
  • openEuler24.03 LTS下安装MySQL8.0.42
  • 气动排渣煤粉炉专用V型球阀——法兰连接耐磨阀门生产厂家解析-耀圣
  • 详解 Zephyr RTOS:架构、功能与开发指南
  • Function Calling
  • 106. 从中序与后序遍历序列构造二叉树
  • 【206】VS2022 C++ 实现无符号32位整数和IP地址字符串互相转换
  • element-ui的el-cascader增加全选按钮实现(附源码)
  • DB-GPT扩展自定义app配置说明
  • 【网络编程】九、详解 HTTPS 加密原理
  • 鸿蒙 ArkUI - ArkTS 组件 官方 UI组件 合集
  • AEO认证的好处 ,如何快速获取AEO认证?
  • Java应用OOM排查:面试通关“三部曲”心法
  • android display 笔记(十四)VAU 和GSP 分别代表什么
  • fpga系列 HDL : Microchip FPGA开发软件 Libero Soc 安装 license申请
  • 企业级Javaweb开发常用注解