Linux 内核在什么情况下会杀死泄漏内存的进程?

Under what condition does Linux Kernel kills a process leaking memory?

我在Linux服务器上检测到我的服务进程泄漏内存,它占用了1.2G的物理内存并且消耗越来越多。

当我查看内存泄漏的代码时,我注意到该进程已重新启动(此进程如果由 supervisord 管理,因此如果被终止也会重新启动)。进程的日志中没有error log,也没有panic。所以我的猜测是它被内核杀死了。

内核什么时候终止泄漏内存的进程?什么时候消耗太多内存?还是分配内存太快?

内存泄漏会导致您的系统内存不足。如果内存非常低,将调用 OOM(Out Of Memory)杀手以尝试从低内存状态中恢复。 OOM Killer 将终止一个或多个消耗更多内存且重要性最低(低优先级)的进程。通常,如果没有可用的用户地址 space 或者没有可用的页面,将调用 OOM 杀手。

OOM killer 使用select_bad_process(),badness() 判断并杀死进程。这些函数根据进程的 VM 大小、子进程的 VM 大小、正常运行时间、优先级、是否进行任何硬件访问、swapper 或 init 等各种因素,通过为所有进程分配 points/score 来确定进程或内核线程。得分最高的过程(坏)获得 terminated/killed。

此外,检查内核的过度使用行为(/proc/sys/vm/overcommit_memory、/proc/sys/vm/overcommit_ratio)和进程的地址限制space是否合适。

在这种情况下,Valgrind 是识别内存泄漏的非常方便的工具。