Linux如何使用perf分析性能瓶颈_Linux perf分析性能瓶颈方案

浅晨同学_4300

浅晨同学_4300

2026-04-04

531人浏览

原创

perf 默认行为易掩盖真实瓶颈,采样前须确认:二进制含debug_info、perf_event_paranoid≤1、进程允许ptrace;cpu密集型应选cycles/instructions事件并计算ipc。

linux如何使用perf分析性能瓶颈_linux perf分析性能瓶颈方案

perf 不是“能用就行”的工具,它默认行为往往掩盖真实瓶颈。直接跑 perf record -g ./app 很可能采不到关键函数、看不到符号、误判热点——尤其在生产环境或优化后期。


采样前必须确认的三件事

没做这三步就开 perf record,90% 的报告会误导你:

  • 目标二进制是否含调试符号?file ./myapp 看输出里有没有 with debug_info;没有就补装 debuginfo 包(如 CentOS 用 debuginfo-install glibc-2.28-XX)
  • 内核是否启用 perf_event_paranoid?运行 cat /proc/sys/kernel/perf_event_paranoid,值 >1 会禁用用户态采样;临时放开: echo 0 | sudo tee /proc/sys/kernel/perf_event_paranoid
  • 进程是否被 ptrace 限制?容器环境(尤其是 rootless Podman 或某些 Kubernetes 安全策略)常默认禁用 ptrace,报错 Operation not permitted 就是这个原因;需加 --cap-add=SYS_PTRACE 或改安全上下文

perf record 的参数组合不能拍脑袋

高频采样(如 -F 999)在高负载进程上会导致严重干扰;低频(-F 10)又可能漏掉短时爆发热点。关键是按问题类型选事件 + 频率:

  • CPU 密集型瓶颈:用 perf record -g -F 99 -e cycles,instructions ./app,之后算 IPC = instructions / cycles,IPC
  • 内存延迟嫌疑:改用 perf mem record -g -a -- sleep 10,它自动启用 mem-loads 和地址采样,比手动配 -e mem-loads,mem-stores 更可靠
  • 锁竞争定位:必须显式启用 tracepoint:perf record -e lock:lock_acquire,lock:lock_release -g -p <pid></pid>,否则 perf report 里根本看不到锁事件
  • 避免默认 cycles 事件被硬件节流干扰:对 Intel CPU,可换用更稳定的 cpu/event=0x00c0,umask=0x00,name=inst_retired_any/(即 retired instructions)

perf report 里看什么、不看什么

默认 perf report 显示的是“带子树聚合”的调用链,容易把底层库函数(如 malloc、memcpy)的开销错误归到上层业务函数名下:

  • 先加 --no-children:看清原始采样分布,确认热点是否真在你的代码里,而不是被 libc 吃掉了
  • 用 -F symbol,dso 显式看模块归属:perf report -F symbol,dso --no-children,区分 myapp、libstdc++.so.6、kernel 的占比
  • 别信“Top Down”树状图:它依赖 CPU 微架构模型(如 Intel TopDown),不同型号解释差异大;优先看 raw sample count 和 period 字段
  • 火焰图不是万能的:perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl 适合快速扫视,但丢失了 perf report 支持的交互式下钻(→/← 键)和符号过滤能力

遇到符号缺失或地址乱码怎么办

看到一堆 [unknown] 或 0x7f8a1b2c3d4e,不是 perf 坏了,而是符号解析链断了:

  • 检查 /proc/<pid>/maps</pid> 里对应地址段是否标记为 r-xp(可执行)且有映射文件路径;若显示 [anon],说明是 JIT 代码(Java/JS/V8)或 mmap 分配的可执行内存,需额外处理
  • 动态链接库未加载符号?运行 perf report --symfs /path/to/debug/build/ 指向含符号的构建目录
  • Go 程序默认 strip 符号:编译时加 -gcflags="all=-N -l",或用 go tool objdump -s "main\." ./mygoapp 辅助对照
  • 内核模块符号缺失:确保安装了对应内核版本的 kmod-debuginfo,并验证 /lib/modules/$(uname -r)/build/ 存在

真正卡住人的从来不是“怎么启动 perf”,而是采样数据出来后,分不清是你的代码慢、系统调用慢、还是硬件在拖后腿。符号链、事件语义、聚合逻辑这三环,漏一环结论就偏。

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.20

2888

5

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5387

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2368

6

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

2023.06.20

4136

8

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.28

1295

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1678

5

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

2023.08.17

9683

11

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

2023.09.01

920

4

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2524

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习