CPU利用率
什么是CPU使用率
Linux是一个典型的分时操作系统,他将每个 CPU 的时间划分为很短的时间片,再通过调度器轮流分配给各个任务使用。Linux 通过事先定义的节拍率(内核中表示为 HZ),触发时间中断,并使用全局变量 Jiffies 记录了开机以来的节拍数。每发生一次时间中断,Jiffies 的值就加 1。节拍率 HZ 是内核的可配选项,可以设置为 100、250、1000 等。可以通过如下命令查看HZ:
root@ubuntu:~# grep 'CONFIG_HZ=' /boot/config-$(uname -r) CONFIG_HZ=250
Linux 通过 /proc 虚拟文件系统,向用户空间提供了系统内部状态的信息。而 /proc/stat 提供的就是系统的 CPU 和任务统计信息。比方说,如果你只关注 CPU 的话,可以执行下面的命令:
root@ubuntu:~# cat /proc/stat | grep ^cpu cpu 58559 723 270633 3250694 69925 0 84380 0 0 0 cpu0 20963 224 77260 742687 4446 0 25589 0 0 0 cpu1 15048 84 59044 843551 22039 0 16268 0 0 0 cpu2 10823 14 64387 837617 21930 0 19589 0 0 0 cpu3 11724 400 69940 826837 21508 0 22932 0 0 0
含义:
-
user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。
-
nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越低。
-
system(通常缩写为 sys),代表内核态 CPU 时间。
-
idle(通常缩写为 id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。
-
iowait(通常缩写为 wa),代表等待 I/O 的 CPU 时间。
-
irq(通常缩写为 hi),代表处理硬中断的 CPU 时间。
-
softirq(通常缩写为 si),代表处理软中断的 CPU 时间。
-
steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。
-
guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。
-
guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。
CPU 使用率,就是除了空闲时间外的其他时间占总 CPU 时间的百分比,用公式来表示就是:

事实上,为了计算 CPU 使用率,性能工具一般都会取间隔一段时间(比如 3 秒)的两次值,作差后,再计算出这段时间内的平均 CPU 使用率,即

这个公式,就是我们用各种性能工具所看到的 CPU 使用率的实际计算方法。
Linux 也给每个进程提供了运行情况的统计信息,也就是 /proc/[pid]/stat。
如何观察CPU使用率
使用top命令查看CPU使用率:
root@ubuntu:~# top top - 09:06:01 up 2:55, 4 users, load average: 1.30, 0.31, 0.39 Tasks: 250 total, 3 running, 247 sleeping, 0 stopped, 0 zombie %Cpu0 : 18.0 us, 62.5 sy, 0.0 ni, 14.0 id, 2.6 wa, 0.0 hi, 2.9 si, 0.0 st %Cpu1 : 4.4 us, 13.0 sy, 0.0 ni, 65.9 id, 10.9 wa, 0.0 hi, 5.8 si, 0.0 st %Cpu2 : 13.3 us, 17.7 sy, 0.0 ni, 56.3 id, 8.2 wa, 0.0 hi, 4.4 si, 0.0 st %Cpu3 : 6.8 us, 38.1 sy, 0.0 ni, 44.6 id, 4.1 wa, 0.0 hi, 6.5 si, 0.0 st MiB Mem : 7903.8 total, 5885.4 free, 400.1 used, 1618.3 buff/cache MiB Swap: 0.0 total, 0.0 free, 0.0 used. 7219.7 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 4256 root 20 0 58072 848 0 R 92.4 0.0 0:23.00 stress-ng 4213 root 20 0 0 0 0 R 34.1 0.0 0:20.85 kworker/u256:0+flush-253:0 4255 root 20 0 58072 848 0 D 32.1 0.0 0:05.98 stress-ng 4224 root 20 0 0 0 0 I 12.6 0.0 0:04.28 kworker/u256:2-ext4-rsv-conversion 4234 root 20 0 0 0 0 I 10.3 0.0 0:05.87 kworker/u256:1-events_power_efficient 472 root 20 0 0 0 0 S 4.3 0.0 1:36.52 jbd2/dm-0-8 759 root 20 0 314836 9128 7548 S 1.3 0.1 1:17.64 vmtoolsd
第一行:系统启动时间,平均负载
第二行:系统进程(任务)统计信息
第三-六行:各CPU使用统计信息
第七行:内存使用统计信息
第八行:swap内存使用统计
剩余部分:各进程占用资源统计信息
使用pidstat查看CPU统计信息:
root@ubuntu:~# pidstat -u 3 Linux 5.15.0-78-generic (ubuntu) 08/14/2023 _x86_64_ (4 CPU) 09:08:49 AM UID PID %usr %system %guest %wait %CPU CPU Command 09:08:52 AM 0 14 0.00 2.63 0.00 0.33 2.63 1 rcu_sched 09:08:52 AM 0 152 0.00 1.64 0.00 0.00 1.64 1 kworker/1:1H-kblockd 09:08:52 AM 0 197 0.00 1.64 0.00 0.66 1.64 3 kworker/3:1H-kblockd 09:08:52 AM 0 272 0.00 0.99 0.00 0.33 0.99 2 kworker/2:1H-kblockd 09:08:52 AM 0 472 0.00 6.91 0.00 1.97 6.91 1 jbd2/dm-0-8 09:08:52 AM 0 759 0.66 0.33 0.00 0.00 0.99 3 vmtoolsd 09:08:52 AM 0 936 0.00 0.33 0.00 0.00 0.33 0 containerd 09:08:52 AM 0 3500 0.00 0.33 0.00 0.00 0.33 3 kworker/3:0-mm_percpu_wq 09:08:52 AM 0 3505 0.00 0.33 0.00 0.00 0.33 2 kworker/2:0-mm_percpu_wq 09:08:52 AM 0 3521 0.00 0.33 0.00 0.00 0.33 0 kworker/0:2-mm_percpu_wq 09:08:52 AM 0 3942 0.00 0.33 0.00 0.00 0.33 1 kworker/1:1-mm_percpu_wq 09:08:52 AM 0 4213 0.00 2.63 0.00 0.00 2.63 2 kworker/u256:0-flush-253:0 09:08:52 AM 0 4234 0.00 8.22 0.00 0.99 8.22 2 kworker/u256:1-writeback 09:08:52 AM 0 4255 3.95 24.67 0.00 4.28 28.62 2 stress-ng 09:08:52 AM 0 4256 37.50 55.59 0.00 0.66 93.09 0 stress-ng 09:08:52 AM 0 4258 0.00 17.43 0.00 0.66 17.43 2 kworker/u256:4-flush-253:0 09:08:52 AM 0 4259 0.00 24.34 0.00 1.64 24.34 3 kworker/u256:5-ext4-rsv-conversion 09:08:52 AM 0 4261 0.33 0.99 0.00 0.00 1.32 1 pidstat
CPU使用率过高怎么办
1. 使用top或者pidstat观察 是否能找出占用cpu的进程,如果不能找出,就怀疑是大量临时任务或进程在占用cpu,从而导致top或pidstat无法观察到。
2. 如果能找出对应的进程,则使用perf工具 对进程进行采样,分析(Java可采用arthas生成火焰图),找出占用CPU的代码。
使用perf record -g -p xxx 进行采样(xxx为进程ID),-g表示启用调用关系分析。采样一段时间后,停止。然后使用perf report命令进行分析。
Samples: 5K of event 'cpu-clock:pppH', Event count (approx.): 1433750000 Children Self Command Shared Object Symbol + 95.80% 0.00% php-fpm [unknown] [k] 0x5706258d4c544155 + 95.80% 0.00% php-fpm libc-2.24.so [.] __libc_start_main + 39.70% 0.00% php-fpm [kernel.kallsyms] [k] entry_SYSCALL_64_after_hwframe + 39.02% 0.07% php-fpm [kernel.kallsyms] [k] do_syscall_64 + 25.09% 0.00% php-fpm php-fpm [.] 0x0000557e39dca8af + 24.62% 0.31% php-fpm php-fpm [.] php_request_startup + 23.54% 0.00% php-fpm php-fpm [.] 0x0000557e39dcad0d + 23.16% 0.10% php-fpm php-fpm [.] php_request_shutdown + 19.63% 0.00% php-fpm php-fpm [.] 0x0000557e39dcabf5 + 16.79% 0.44% php-fpm php-fpm [.] php_execute_script + 15.92% 0.03% php-fpm php-fpm [.] sapi_deactivate + 15.66% 0.00% php-fpm php-fpm [.] 0x0000557e39dc7e8c + 13.55% 0.00% php-fpm php-fpm [.] 0x0000557e39dca8a0 + 10.74% 0.09% php-fpm php-fpm [.] tsrm_realpath + 10.71% 0.00% php-fpm php-fpm [.] 0x0000557e39dc8792
-
Overhead ,是该符号的性能事件在所有采样中的比例,用百分比来表示。
-
Shared ,是该函数或指令所在的动态共享对象(Dynamic Shared Object),如内核、进程名、动态链接库名、内核模块名等。
-
Object ,是动态共享对象的类型。比如 [.] 表示用户空间的可执行程序、或者动态链接库,而 [k] 则表示内核空间。
-
Symbol 是符号名,也就是函数名。当函数名未知时,用十六进制的地址来表示。
-
Self 是最后一列的符号(可以理解为函数)本身所占比例;
-
Children 是这个符号调用的其他符号(可以理解为子函数,包括直接和间接调用)占用的比例之和。
浙公网安备 33010602011771号