Linux高CPU进程排查_top与perf结合

6次阅读

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

Linux 高 CPU 进程排查_top 与 perf 结合

当 Linux 系统出现 CPU 使用率飙升时,单靠 top 只能看到哪个进程在“吃”CPU,但无法知道它到底在执行什么代码——是死循环?锁竞争?还是频繁的系统调用?这时需要 perf 深入函数级甚至指令级分析,topperf 配合,才能快速定位根因。

用 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 不会直接告诉你“怎么改代码”,但它会精准指出“哪一行附近最热”。结合源码和上下文,修复方向就很清晰了。

text=ZqhQzanResources