Linux 下如何排查 CPU 以及 内存占用过多?
一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环。 下面我们将一步步定位问题,详尽的介绍每一步骤的相关知识。
# 一、通过top命令定位占用cpu高的进程
执行top命令得到以下结果:
top命令执行结果
通过上图可以明显看出进程PID41843占用cpu过高,明显存在问题,定位到了进程id。当然如果你想只观察进程PID41843的CPU和内存以及负载情况,可以使用以下命令
top -p 41843。
结果如下:
top -p 41843命令执行结果
这里顺便解释下上图各个参数的意义,有利于读者更好的排查问题。
- 第一行是任务队列信息 top - 14:06:34 up 537 days, 6 min, 6 users, load average: 0.41, 0.45, 0.43
任务队列信息 | 含义 |
---|---|
14:06:34 | 当前时间 |
537 days | 系统运行时间 |
6 min | 用户在线时间 |
6 users | 在线用户数 |
load average: 0.41, 0.45, 0.43 | 系统负载,即任务队列的平均长度。1分钟前、5分钟前、15分钟前平均负载 |
2)第二行为进程的信息
进程信息 | 含义 |
---|---|
Tasks: 1 total | 进程总数 |
0 running | 正在运行的进程数 |
1 sleeping | 睡眠的进程数 |
0 stopped | 停止的进程数 |
0 zombie | 僵尸进程数 |
- 第三行为cpu信息
cpu信息 | 含义 |
---|---|
6.1% us | 用户空间占用CPU百分比 |
1.5% sy | 内核空间占用CPU百分比 |
0.0% ni | 用户进程空间内改变过优先级的进程占用CPU百分比 |
92.2% id | 空闲CPU百分比 |
0.0% wa | 等待输入输出的CPU时间百分比 |
0.0% hi | 硬件中断 |
0.0% si | 软件中断 |
0.0%st | 实时 |
- 第四、五行为内存信息。 内容如下:
物理内存信息 | 含义 |
---|---|
Mem: 191272k total | 物理内存总量 |
173656k used | 使用的物理内存总量 |
17616k free | 空闲内存总量 |
22052k buffers | 用作内核缓存的内存量 |
交换区信息 | 含义 |
---|---|
Swap: 192772k total | 交换区总量 |
0k used | 使用的交换区总量 |
192772k free | 空闲交换区总量 |
123988k cached | 缓冲的交换区总量 |
# 二、通过top命令定位问题进程中每个线程占用cpu情况
通过问题进程中每个线程占用cpu情况使用可以使用如下命令:
top -p 41843 -H
查看进程PID41843的每一个线程占用CPU情况,如图。
top -p 41843 -H的执行结果
由上图明显可以发现,线程PID41892CPU占用率最高,接下来定位该线程的代码是否出现异常导致cpu占用过高。
# 三、通过jstack 命令定位问题代码
上一步发现PID41892占用的CPU过高,就将这个PID转换成16进制,易知,PID41892转化成16进制为a3a4。使用如下命令命令定位问题代码:
jstack 41892 | grep a3a4
输出如下:
"Thread" prio=10 tid=0x00007f950043e000 nid=0x54ee in test();
可以分析得到: 线程Thread下的wait()函数cpu使用率很高,查看源代码中的test()函数代码如下:
public void test(){
while(true){
for(int i = 0 ;i<100;i++);
}
}
1
2
3
4
5
2
3
4
5
while循环无法结束,一直抢占cpu,导致程序cpu使用过高,修改代码即可。 到此为止,因为代码问题导致的cpu使用过高的故障排查方法就介绍完了。
编辑 (opens new window)
上次更新: 2023/02/17, 17:03:51