问题描述
根据我的理解,当系统接近没有空闲内存时,内核应该开始杀死进程以重新获得一些内存。但在我的系统中,这根本不会发生。
假设一个简单的脚本只分配比系统中可用内存多得多的内存(例如,一个包含数百万字符串的数组)。如果我运行这样的脚本(作为普通用户),它只会获取所有内存,直到系统完全冻结(只有SysRQ REISUB工作)。
这里奇怪的部分是,当计算机冻结时,硬盘驱动器会打开并保持这种状态直到计算机重新启动,无论是否安装了交换分区!
所以我的问题是:
-
这种行为是否正常?奇怪的是,作为普通用户执行的应用程序可能会以这种方式使系统崩溃……
-
有什么方法可以让Ubuntu在他们获得太多(或最多)内存时自动杀死这些应用程序?
附加信息
-
Ubuntu 12.04.3
-
内核3.5.0-44
-
RAM:从4GB到大约3.7GB(与显卡共享)。 *
$ tail -n+1 /proc/sys/vm/overcommit_* ==> /proc/sys/vm/overcommit_memory <== 0 ==> /proc/sys/vm/overcommit_ratio <== 50 $ cat /proc/swaps Filename Type Size Used Priority /dev/dm-1 partition 4194300 344696 -1
最佳解决思路
从官方/proc/sys/vm/*
文档:
oom_kill_allocating_task
This enables or disables killing the OOM-triggering task in out-of-memory situations.
If this is set to zero, the OOM killer will scan through the entire tasklist and select a task based on heuristics to kill. This normally selects a rogue memory-hogging task that frees up a large amount of memory when killed.
If this is set to non-zero, the OOM killer simply kills the task that triggered the out-of-memory condition. This avoids the expensive tasklist scan.
If panic_on_oom is selected, it takes precedence over whatever value is used in oom_kill_allocating_task.
The default value is 0.
总而言之,当将oom_kill_allocating_task
设置为1
时,内核只会杀死导致系统内存不足的进程,而不是扫描你的系统寻找要杀死的进程,这是一项昂贵且缓慢的任务。
根据我自己的经验,当触发OOM时,内核不再有足够的”strength”进行此类扫描,使系统完全无法使用。
此外,更明显的是杀死导致问题的任务,所以我无法理解为什么默认设置为0
。
对于测试,您可以在/proc/sys/vm/
中写入正确的pseudo-file,它将在下次重新启动时撤消:
echo 1 | sudo tee /proc/sys/vm/oom_kill_allocating_task
要进行永久性修复,请将以下内容写入/etc/sysctl.conf
或/etc/sysctl.d/
下的新文件,并使用.conf
扩展名(例如/etc/sysctl.d/local.conf
):
vm.oom_kill_allocating_task = 1
次佳解决思路
更新:错误已修复。
Teresa’s answer足以解决问题并且很好。
另外,我已经提交了a bug report,因为这绝对是一种破坏的行为。