前段时间一直运行的模型因为访问量激增,突然出现了CPU内存翻倍无法自己下降的情况,必须重启服务器。虽然平时负责算法研发和移植工作多,但是自己一直对高性能系统都很感兴趣。所以当时除了配合服务端的人排查问题,也去请教了公司一直做后台开发的大佬,学习了一番。对于Linux系统,程序功能执行结束而内存一直无法释放,本质的原因是该程序的进程尚未结束。但Linux系统的内存管理其实是非常复杂的一个系统,当初系统内存回收机制的设计本身就是有一定的概率会找不到无用内存的。因此,当发现CPU内存飙高无法自降时,需要从代码以及系统层面去分析和确定问题。然而,目前来说,对于linux系统,没有非常好的内存查找工具可用。所以更多的时候是靠自己的经验以及对操作系统的理解。这篇文章,有很多也是借鉴了大牛的知识,写得不对的地方,欢迎大家过来补充和修正。
首先,来看看Linux系统资源消耗点的分布:
一般来说,CPU,load以及IO都是比较耗内存的地方。在2.6版本后的内核里,进程一般有7种状态。分别是:不可中断睡眠态(TASK_UNINTERRUPTIBLE)、可执行态(TASK_RUNNING)、可中断睡眠态(TASK_INTERRUPTIBLE)、暂停&跟踪状态(__TASK_STOPPED & __TASK_TRACED)、僵尸态(EXIT_ZOMBIE)和死亡态(EXIT_DEAD)。
各状态的含义如下:
不可中断睡眠态:位于这种状态的进程处于睡眠中,并且不允许被其他进程或中断(异步信号)打断。因此这种状态的进程,是无法使用kill -9杀死的(kill也是一种信号),除非重启系统(没错,就是这么头硬)。不过这种状态一般由I/O等待(比如磁盘I/O、网络I/O、外设I/O等)引起,出现时间非常短暂,大多很难被PS或者TOP命令捕获(除非I/O HANG死)。SLEEP态进程不会占用任何CPU资源。
可中断睡眠态:这种状态的进程虽然也处于睡眠中,但是