news 2026/4/15 12:15:38

Linux性能优化之CPU利用率

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux性能优化之CPU利用率

写在前面

本文看下CPU使用率相关内容。

1:Linux是如何维护CPU时间的?如何查看CPU使用率?

1.1:Linux是如何维护CPU时间的?

先来看下节拍率的概念,通过HZ表示,一般是100,250,1000这样的值,如下查看:

root@dongyunqi:/home/dongyunqi/study/jdk1.8.0_152/jdk8u482-b08# grep 'CONFIG_HZ=' /boot/config-$(uname -r) CONFIG_HZ=1000

代表每秒会发生1000次切换,这每一次切换,是一次中断,两次中断之间的时间叫做一个滴答,即tick。那么cpu时间片和tick是什么关系呢?是这样子的,linux会将时间片定义为tick的整数值,比如一个时间片等于3*tick,这个时候,一个CPU时间片的长度就是3毫秒了。那CPU时间是通过时间片切换次数,再换算成滴答数,从而得到运行时间的吗?不是的,因为这样计算的结果误差太大了。试想下CPU时间只能以毫秒为单位,力度也太大了。其实CPU时间的计算,在linux中是通过TSC,即time stamp counter来计算的,其计算的精度更高,可以到纳秒级,精度很高很高了。
那么该如何查看CPU时间,通过命令cat /proc/stat | grep ^cpu可以看整个系统的CPU时间,如下:

root@dongyunqi:/home/dongyunqi/study# cat /proc/stat | grep ^cpu cpu 1935124 1976 5114477 4277863 2086 0 20396 0 0 0 cpu0 1935124 1976 5114477 4277863 2086 0 20396 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时间,可以通过/proc/[pid]/stat查看。

1.2:如何查看CPU使用率?

我们知道了可以通过查看相关的系统数据来获取不同状态的CPU时间,那么当我们要计算的时候难道要自己来计算吗?这也太麻烦了,当然不用,Linux已经给我们准备好了各种命令了,比如最常用的top,以及pidstat等。

^Croot@dongyunqi:/home/dongyunqi/study# pidstat 5 1 Linux 6.8.0-106-generic (dongyunqi) 04/03/2026 _x86_64_ (1 CPU) 05:34:43 PM UID PID %usr %system %guest %wait %CPU CPU Command 05:34:48 PM 0 6253 0.00 0.20 0.00 0.20 0.20 0 kworker/u256:2-events_power_efficient 05:34:48 PM 0 6273 0.00 0.20 0.00 0.00 0.20 0 kworker/0:2-events 05:34:48 PM 0 6363 0.00 0.60 0.00 0.00 0.60 0 pidstat Average: UID PID %usr %system %guest %wait %CPU CPU Command Average: 0 6253 0.00 0.20 0.00 0.20 0.20 - kworker/u256:2-events_power_efficient Average: 0 6273 0.00 0.20 0.00 0.00 0.20 - kworker/0:2-events Average: 0 6363 0.00 0.60 0.00 0.00 0.60 - pidstat

2:实战CPU问题排查

我们准备如下的程序:

packagedongshi.daddy.zhengxi;importjava.util.ArrayList;importjava.util.List;importjava.util.Random;publicclassManyCpu{privatestaticList<Long>myList=newArrayList<>();publicstaticvoidmain(String[]args){newThread(()->{while(true){intaa=88888888+newRandom().nextInt(10000);intbb=98888888+newRandom().nextInt(10000);System.out.println(aa*bb);System.out.println((aa+1)*bb);System.out.println(aa*(bb+1));}},"thread-testmanycpu").start();}}

编译运行:

root@dongyunqi:/home/dongyunqi/study# javac -d . ManyCpu.java root@dongyunqi:/home/dongyunqi/study# ls cpu_stress.sh dongshi jdk1.8.0_152 ManyCpu.java packages root@dongyunqi:/home/dongyunqi/study# java dongshi.daddy.zhengxi.ManyCpu

使用pidstat查看cpu使用率:

root@dongyunqi:/home/dongyunqi# top top - 17:47:35 up 1 day, 8:13, 6 users, load average: 1.71, 1.07, 1.00 Tasks: 230 total, 1 running, 229 sleeping, 0 stopped, 0 zombie %Cpu(s): 98.0 us, 2.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 1920.3 total, 292.8 free, 509.6 used, 1296.7 buff/cache MiB Swap: 1899.0 total, 1898.7 free, 0.3 used. 1410.7 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 6723 root 20 0 2375824 41948 16852 S 98.7 2.1 1:26.84 java ...

可以看到我们的Java进程,已经占用了98.7%的CPU了,接着来看下进程中哪个线程占用了CPU:

root@dongyunqi:/home/dongyunqi# top -Hp 6723 top - 17:49:19 up 1 day, 8:15, 6 users, load average: 1.18, 1.06, 1.00 Threads: 11 total, 1 running, 10 sleeping, 0 stopped, 0 zombie %Cpu(s): 98.7 us, 1.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 1920.3 total, 292.8 free, 509.5 used, 1296.8 buff/cache MiB Swap: 1899.0 total, 1898.7 free, 0.3 used. 1410.8 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 6733 root 20 0 2375824 41948 16852 R 95.3 2.1 2:59.11 thread-testmany ...

可以看到线程ID是6733,接着我们需要查看该线程执行的方法是啥,命令jstack [进程id] | grep [线程id十六进制]如下:

红框就是造成CPU高的位置了。

3:不同场景的CPU问题排查实战

排查CPU问题的常见指标如下:

1:用户cpu使用率高 2:syscpu使用率高 3:等待IO CPU使用率 4:中断CPU使用率 5:平均负载 6:上下文切换 7:CPU缓存命中率

3.1:用户cpu使用率高

需要注意的是,排查某一类问题,可以用到的命令都不止一个,正所谓条条大路通罗马,但重要的是,当遇到某一类问题时,现有一个清晰的排查思路,然后才是触类旁通,融会贯通,所以不用纠结说,诶这个我用这个命令不是也可以吗?干嘛要用那个命令这种。

3.1.1:Java项目

参考本文2:实战CPU问题排查。用到的命令是:

1:top 定位占用CPU最多的进程 2:top -Hp 定位进程中占用CPU最多的线程 3:printf '%x\n' [线程号] 将线程号转为16进制,因为jstack命令中的线程号是16进制表示的 4:jstack [进程id] | grep [16进制线程号] -A 20 定位出具体的代码位置

3.1.2:TODO项目

3.2:syscpu使用率高

3.3:等待IO CPU使用率

参考这篇文章 。
核心思路是,首先通过watch -d utime命令,观察负载的变化情况,发现在不断的升高后,通过命令mpstat -P ALL 5获取看下每个核的CPU利用率情况,发现异常后可以进一步通过pidstat -u 5获取哪个进程占用的CPU利用率高或者时IOWAIT高。再做进一步排查。

3.4:中断CPU使用率

参考 。
如果怀疑是中断造成了CPU使用率高的话,可以通过命令watch -d "/bin/cat /proc/softirqs | /usr/bin/awk 'NR == 1{printf \"%13s %s\n\",\" \",\$1}; NR > 1{printf \"%13s %s\n\",\$1,\$2}'"查看各种软中断的次数,主要还是看是否在一直增大。一般出问题的是NET_*相关的,即网络发包和收包。

3.5:平均负载

参考这篇文章 。
核心思路是,首先通过watch -d utime命令,观察负载的变化情况,发现在不断的升高后,通过命令mpstat -P ALL 5获取看下每个核的CPU利用率情况,发现异常后可以进一步通过pidstat -u 5获取哪个进程占用的CPU利用率高或者时IOWAIT高。再做进一步排查。

3.6:上下文切换

点我 。
观察到CPU高,如果是怀疑上下文切换造成的,可以使用命令vmstat 1观察上下文切换次数,如果是超过一万,并且在不断增加的话,基本可以断定,上下文切换次数过多了。接着可以通过pidstat -wt 1命令看下哪个进程上下文切换次数过多了。

3.7:CPU缓存命中率

写在后面

参考文章列表

多知道一点

CPU问题排查可能用到的命令:

iowait高会导致CPU利用率高吗?

不会。cpu使用率一般是user+sys的总和,如下图:

iowait高可能会导致负载高,因为iowait参数计算负载值。因为iowait的线程或进程处于不可打断状态。这里只是一个状态而已,可以认为时一个特殊的标记吧,因此当有其他线程或进程需要CPU资源时依然会切换过去执行。
另外注意,iowait 特指等待磁盘 I/O 的时间,与网络 I/O 完全无关。这可能是一个常见的误区,至少我开始是这样认为的。

iowait高会导致CPU利用率高吗?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 12:14:35

C++函数模板实战:如何设计一个通用的“比较器”

1. 为什么我们需要通用的比较器&#xff1f; 在日常开发中&#xff0c;经常会遇到需要比较两个值大小的情况。比如电商系统要比较商品价格&#xff0c;社交平台要筛选用户评分最高的内容&#xff0c;或者文件管理系统需要对文件名进行排序。如果为每种数据类型都单独写一个比较…

作者头像 李华
网站建设 2026/4/15 12:13:14

HCPL-2400-060E,10kV/µs高速三态输出TTL兼容逻辑门光耦合器

简介今天我要向大家介绍的是 Broadcom 的光耦合器——HCPL-2400-060E。它是一款单通道、兼容 TTL、STTL、LSTTL 和 HCMOS 逻辑的高速逻辑门光耦合器。该器件内部采用 820 nm AlGaAs 发光二极管技术&#xff0c;并结合了高速光探测器。其输出端为带有内置施密特触发器的三态输出…

作者头像 李华
网站建设 2026/4/15 12:10:28

【稀缺首发】多模态域适应的4层黄金评估体系:含37项量化指标、12个基准数据集对比矩阵与可复现代码包

第一章&#xff1a;多模态大模型域适应技术 2026奇点智能技术大会(https://ml-summit.org) 多模态大模型在跨域场景下常面临语义鸿沟、模态失配与分布偏移等核心挑战。域适应技术旨在缓解源域&#xff08;如Web图像-文本对&#xff09;与目标域&#xff08;如医学影像报告&…

作者头像 李华
网站建设 2026/4/15 12:08:35

如何用百元硬件打造专业级开源无人机:ESP-Drone完整指南

如何用百元硬件打造专业级开源无人机&#xff1a;ESP-Drone完整指南 【免费下载链接】esp-drone Mini Drone/Quadcopter Firmware for ESP32 and ESP32-S Series SoCs. 项目地址: https://gitcode.com/GitHub_Trending/es/esp-drone 你是否曾梦想亲手打造一架属于自己的…

作者头像 李华