Linux性能优化-系统存在大量不可中断的进程和僵尸进程怎么办
不可中断进程和僵尸进程
- 不可中断进程,一般是指在进程在和硬件交互为了保护进程数据和硬件一致,系统不允许其他进程中断打断该进程。
- 僵尸进程表示进程已经退出,但是它的父进程没有回收该进程所占用的资源。
进程运行状态
- R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。
- D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。
- Z 是 Zombie 的缩写,如果你玩过“植物大战僵尸”这款游戏,应该知道它的意思。它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。
- S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。
- I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会。
当然了,上面的示例并没有包括进程的所有状态。除了以上 5 个状态,进程还包括下面这 2 个状态。
第一个是 T 或者 t,也就是 Stopped 或 Traced 的缩写,表示进程处于暂停或者跟踪状态。向一个进程发送 SIGSTOP 信号,它就会因响应这个信号变成暂停状态(Stopped);再向它发送 SIGCONT 信号,进程又会恢复运行(如果进程是终端里直接启动的,则需要你用 fg 命令,恢复到前台运行)。
而当你用调试器(如 gdb)调试一个进程时,在使用断点中断进程后,进程就会变成跟踪状态,这其实也是一种特殊的暂停状态,只不过你可以用调试器来跟踪并按需要控制进程的运行。
另一个是 X,也就是 Dead 的缩写,表示进程已经消亡,所以你不会在 top 或者 ps 命令中看到它。
现象:
1.iowait太高,导致负载升高,并且达到了系统CPU的个数
2.僵尸进程不断增多
分析:
一、先分析iowait升高的原因,可能的原因是i/o问题
1.使用dstat命令查询CPU和I/O的使用情况(查看read,write请求的情况)
# 间隔1秒输出10组数据
$ dstat 1 10
2.使用top或ps查看D状态的进程
$ top
3.使用pidstat加-d参数输出I/O使用的情况
# -d展示I/O统计数据,-p指定进程号,间隔1秒输出3组数据
$ pidstat -d -p [进程号] 1 3
4.如果通过上面的方法查看进程发现没有磁盘读写的信息,那就直接查看所有进程的I/O使用情况
# 间隔1秒输出多组数据
$ pidstat -d 1 20
5.进程直接访问磁盘就必须使用系统调用,现在来找出进程的系统调用
$ strace -p [进程号]
或者使用:
$ perf record -g
$ perf report
二、僵尸进程
1.找出僵尸进程的父进程
# -a表示命令行选项,p表示PID,s表示制定进程的父进程
$ pstree -aps [僵尸进程PID] #这里僵尸进程是3084
systemd,1
└─dockerd,15006 -H fd://
└─docker-containe,15024 --config /var/run/docker/containerd/containerd.toml
└─docker-containe,3991 -namespace moby -workdir...
└─app,4009
└─(app,3084)
# -A 参数列出所有进程,
# -o 自定义输出字段 我们设定显示字段为 stat(状态), ppid(进程父id), pid(进程id),cmd(命令)这四个参数
# grep -e 过滤查找做为查找Zz文件内容的样式
$ ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]'
3084 号进程的父进程是 4009
接着查看应用程序的代码,看看子进程结束的处理是否正确,比如有没有调用 wait() 或 waitpid() ,抑或是,有没有注册 SIGCHLD 信号的处理函数。
2.杀死僵尸进程的父进程
由于僵尸进程已经死掉了(只保留了 task_struct 结构体),而死掉的进程是无法直接 kill 的,所以一般通过杀掉父进程来间接干掉僵尸进程。
把父进程杀掉,僵尸进程会变成孤儿进程,然后过继给 1 号进程,而 1 号进程会扫描名下子进程,把 Z 状态进程回收;
$ kill -9 [僵尸进程父进程PID]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)