我在 Ubuntu 12.04 下观察到以下行为:
在具有 24GB RAM 和 24 个 CPU 的系统上,如果单个进程获得 ~12GB 的 RAM,则属于高内存进程所有者的所有其他进程都会在没有警告的情况下被杀死,使用看似 SIGKILL 的方法,并且高内存进程允许运行直到终止。此外,所有者尝试启动新进程将失败。
这有点麻烦,但我更好奇它为什么会发生。大概这是内核中资源调度决策的结果。有没有地方可以找到这方面的文档?
我在 Ubuntu 12.04 下观察到以下行为:
在具有 24GB RAM 和 24 个 CPU 的系统上,如果单个进程获得 ~12GB 的 RAM,则属于高内存进程所有者的所有其他进程都会在没有警告的情况下被杀死,使用看似 SIGKILL 的方法,并且高内存进程允许运行直到终止。此外,所有者尝试启动新进程将失败。
这有点麻烦,但我更好奇它为什么会发生。大概这是内核中资源调度决策的结果。有没有地方可以找到这方面的文档?
很抱歉回答我自己的问题,但我喜欢记录解决方案。锯末链接的文章包含我需要的内容。
就我而言,有两个原因导致除了占用内存的进程之外的所有进程都被杀死。
我的进程在分配内存的区域期间忽略 SIGTERM。这可能是因为该进程在这段时间内正在积极接收许多其他信号,和/或因为该进程在剩余的大部分时间里都在阻塞 I/O。在任何情况下,它都会忽略 SIGTERM。
占用所有内存的进程通常已经运行了很长时间,积累了几个小时的 RAM。尽管它的运行时间大约是其他任何进程的 4 倍,但它的运行时间很长(比其他进程长数百倍)可能会导致 OOM 管理器选择其他进程首先终止。
解决方案:
跑步:
ulimit -v memamount
对于特定用户,将用户可以使用单个进程分配的最大内存量更改为 memamount。这可以防止 OOM 管理器激活。相反, malloc 调用将失败,我可以检测到。
2:为 SIGTERM 编写一个优雅地清理的处理程序可能会有所帮助,但前提是 OOM 实际上正在向进程发送 SIGTERM,并且进程忽略或无法接收 SIGTERM。
3:从您的代码(C)中设置内存限制:
//resource limit structure with both hard and soft max set to 2GB.
struct rlimit memmax; memmax.rlim_max=0x7FFFFFFF; memmax.rlim_cur = 0x7FFFFFFF;
setrlimit(RLIMIT_MEMLOCK,&memmax); //set maximum virtual memory space to 2GB.