据我所知,当系统快没有可用内存时,内核应该开始终止进程以重新获得一些内存。但在我的系统中,这种情况根本没有发生。
假设一个简单的脚本分配的内存比系统可用的内存多得多(例如,一个包含数百万个字符串的数组)。如果我运行这样的脚本(以普通用户身份),它会获取所有内存,直到系统完全冻结(只有 SysRQ REISUB 有效)。
这里奇怪的是,当计算机冻结时,硬盘 LED 会亮起并保持这种状态,直到计算机重新启动,无论我是否安装了交换分区!
我的问题是:
- 这种行为正常吗?以普通用户身份执行的应用程序竟然会以这种方式导致系统崩溃,这很奇怪...
- 有什么方法可以让 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
答案1
oom_kill_allocating_task
这将启用或禁用在内存不足的情况下终止触发 OOM 的任务。
如果将其设置为零,OOM 终止程序将扫描整个任务列表并根据启发式方法选择一个任务进行终止。这通常会选择一个占用大量内存的恶意任务,该任务在终止时会释放大量内存。
如果将其设置为非零,OOM 终止程序将直接终止触发内存不足情况的任务。这样可以避免昂贵的任务列表扫描。
如果选择了 panic_on_oom,它优先于 oom_kill_allocating_task 中使用的任何值。
默认值为 0。
总而言之,当设置oom_kill_allocating_task
为 时1
,内核将直接终止导致系统内存不足的进程,而不是扫描系统来寻找需要终止的进程(这是一项昂贵而缓慢的任务)。
根据我自己的经验,当触发 OOM 时,内核已经没有足够的“力量”来进行这样的扫描,从而导致系统完全无法使用。
此外,仅仅终止导致问题的任务会更加明显,所以我不明白为什么0
默认设置如此。
为了进行测试,您只需写入正确的伪文件即可/proc/sys/vm/
,该操作将在下次重新启动时撤消:
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
答案2
答案3
你可以试试早期,一个在用户空间运行的 OOM 杀手,它试图在 OOM 情况下杀死最大的进程。
答案4
首先,我建议更新到 13.10(全新安装,保存数据)。
如果您不想更新,请将 vm.swappiness 更改为 10,如果发现 RAM 存在问题,请安装 zRAM。