这篇文章上次修改于 761 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

1 查看 CPU 使用率

在查看 CPU 使用率时,top 默认为 3s 的间隔,ps 使用的是进程的整个生命周期。

使用 top 时,按下数字 1 就可以切换到每个 CPU 的使用率。

pidstat 可以查看每个进程的 CPU 使用率。

# -u 表示显示各个 CPU 的使用统计
# 5 表示每 5s 采样一次
# 1 表示一共采样 1 次
$ pidstat -u 5 1
Linux 4.15.0-142-generic (ubuntu)     2021年09月25日     _x86_64_    (16 CPU)

16时17分53秒   UID       PID    %usr %system  %guest    %CPU   CPU  Command
16时17分58秒   111      1106    0.20    0.20    0.00    0.40     8  avahi-daemon
16时17分58秒   123      1411    1.60    0.40    0.00    2.00     8  nxserver.bin
16时17分58秒  1000      7387  100.20    0.00    0.00  100.20     4  stress

Average:      UID       PID    %usr %system  %guest    %CPU   CPU  Command
Average:      111      1106    0.20    0.20    0.00    0.40     -  avahi-daemon
Average:      123      1411    1.60    0.40    0.00    2.00     -  nxserver.bin
Average:     1000      7387  100.20    0.00    0.00  100.20     -  stress
  • usr 用户态 CPU 使用率
  • system 内核态 CPU 使用率
  • guest 运行虚拟机 CPU 使用率
  • wait 等待 CPU 使用率
  • CPU 总的 CPU 使用率

2 CPU 使用率过高怎么办

如果发现了 CPU 使用率过高的进程,接下来,如何知道占用 CPU 的到底是哪个函数呢?可以用 perf。

$ perf top
Overhead  Shared Object                  Symbol
   7.55%  perf                           [.] __symbols__insert
   5.61%  libavahi-common.so.3.5.3       [.] avahi_unescape_label
   4.05%  perf                           [.] rb_next
   2.19%  libc-2.23.so                   [.] strlen
   2.09%  [kernel]                       [k] module_get_kallsym
  • Overhead 该符号的性能事件在所有采样中的比例。
  • Shared 该函数或指令所在的动态共享对象,如内核、进程名、动态链接库、内核模块名等。
  • Object 动态共享对象的类型。如 [.] 表示用户空间等可执行程序、或者动态连接库,[k] 表示内核空间。
  • Symbol 是符号名,即函数名。函数名未知时,用十六进制的地址表示。

perf record 可保存数据,perf report 可解析展示保存后的数据。

当发现某个某个进程的 CPU 使用率过高时,可分析该进程的哪个函数导致的:

# -g 可开启调用关系采样
# -p 指定进程号
$ perf top -g -p 7387

按下回车键可查看调用关系。

3 小节

  • 用户 CPU 和 Nice CPU 高,说明用户态占用了较多 CPU,应着重排查进程的性能问题。
  • 系统 CPU 过高,说明内核态占用了较多的 CPU,应着重排查内核线程或系统调用的性能问题。
  • I/O 等待的 CPU 高,说明等待 I/O 的时间较长,应着重排查系统存储是不是出现了 I/O 问题。
  • 软中断和硬中断高,说明软中断或硬中断处理程序占用了较多的 CPU,应着重排查内核中的中断服务程序。

参考

《Linux性能优化实战》倪鹏飞.