top 与 perf 配合可定位 cpu 飙升根因:top 锁定高 cpu 进程,perf record 采集热点函数,perf report 或火焰图分析耗时代码,再依模式(如锁竞争、内存分配)针对性优化。

当 Linux 系统出现 CPU 使用率飙升时,单靠 top 只能看到哪个进程在“吃”CPU,但无法知道它到底在执行什么代码——是死循环?锁竞争?还是频繁的系统调用?这时需要 perf 深入函数级甚至指令级分析,top与 perf 配合,才能快速定位根因。
用 top 快速锁定高 CPU 进程
top是第一道筛子,重点看几个字段:
- PID:进程唯一标识,后续 perf 采样要用
- %CPU:按实际占用率排序(按
P键),持续高于 80% 且不回落的进程需重点关注 - COMMAND:确认是不是业务关键进程(如 java、nginx、python),避免误杀系统守护进程
- TIME+:累计 CPU 时间,若增长极快,说明该进程近期活跃度异常升高
注意:top 默认刷新间隔是 3 秒,可按 s 键改为 1 秒或 0.5 秒,便于捕捉瞬时尖峰;按 H 可切换线程视图,确认是否某个线程独占 CPU。
用 perf record 抓取热点函数
拿到可疑 PID 后,立即用 perf record 采集栈信息,推荐以下命令:
perf record -g -p <PID> -a -- sleep 10
- -g:开启调用图(call graph),能看清函数调用链,比如
main → handle_request → json_parse → memcpy - -p:指定进程 PID;加
-a可同时捕获其所有线程(含内核线程) - — sleep 10:让 perf 运行 10 秒后自动停止,避免手动中断导致采样不完整
若进程启动不久就飙高,也可用 perf record -g -e cpu-clock:u 只采用户态,减少干扰;对 Java 应用,建议加上-F 99(采样频率 99Hz),避免过度开销。
用 perf report 分析火焰图式热点
执行 perf report -g --no-children 进入交互式报告:
- 按
Enter展开某函数,查看它调用了哪些下层函数 - 关注“Self”列占比高的函数——这是真正耗 CPU 的源头,不是被调用的“背锅侠”
- 若看到大量
[unknown]或__libc_start_main,说明缺少符号表,需安装对应 debuginfo 包(如debuginfo-install glibc)或用perf buildid-list核对二进制版本
更直观的方式是生成火焰图:perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > cpu.svg,打开 SVG 文件,宽底座的函数就是罪魁祸首。
常见模式与对应动作
根据 perf 结果,可快速归类处理:
- 集中在某个业务函数(如 process_order):检查该函数是否有未优化的循环、重复序列化、或阻塞式 IO 混在计算逻辑中
- 大量出现在 malloc/free 或 jemalloc 内部:内存分配频繁,考虑对象池复用、减少临时对象创建
- 停在 futex_wait、pthread_mutex_lock 等同步原语 :存在锁竞争,用
perf lock record进一步分析锁持有时间 - 大量 sys_write、sys_read、epoll_wait:I/ O 密集型,但 CPU 高说明可能在用户态反复拷贝数据(如小包频繁 read/write),应检查缓冲区大小和零拷贝配置
perf 不会直接告诉你“怎么改代码”,但它会精准指出“哪一行附近最热”。结合源码和上下文,修复方向就很清晰了。






























