如何防止 Linux 在内存不足时冻结?

joh*_*ohv 31 linux oom

今天我(不小心)在我的 Linux 机器上运行了一些快速使用大量内存的程序。我的系统死机,反应迟钝,因此我无法杀死罪犯。

我怎样才能在未来防止这种情况?它不能至少保持一个响应式核心或其他东西运行吗?

wom*_*ble 16

我敢打赌,系统实际上并没有“冻结”(在内核挂起的意义上),而是非常没有响应。可能只是交换非常困难,导致交互性能和系统吞吐量像石头一样下降。

可以关闭交换,但这只会将问题从性能低下改为 OOM 终止进程(以及由此产生的所有乐趣),同时由于可用磁盘缓存较少而导致性能下降。

或者,您可以使用每个进程的资源限制(通常称为rlimit和/或ulimit)来消除单个进程占用大量内存并导致交换的可能性,但这只会让您进入娱乐领域,进程在不方便的时刻,因为他们想要比系统愿意给他们更多的内存。

如果你知道你要做一些可能会导致大量内存使用的事情,你可能会写一个包装程序,mlockall()然后执行你的 shell;这会将它保存在内存中,并且将是您可能获得的最接近“保持响应式内核”的方法(因为问题并不是 CPU 被过度使用)。

就我个人而言,我赞成“不要做蠢事”的资源控制方法。如果你有 root,你可以对系统造成各种损害,所以做任何你不知道可能结果的事情都是有风险的。

  • 不幸的是,“不要做愚蠢的事情”对运行 Chrome 等占用大量内存的应用程序的用户没有帮助(请参阅问题 [134612](https://bugs.chromium.org/p/chromium/issues/detail?id= 134612), [393395](https://bugs.chromium.org/p/chromium/issues/detail?id=393395))。 (2认同)
  • @DanDascalescu 而且你在做一些愚蠢的事情并不总是显而易见的。前几天我的机器挂了,因为我将(复杂的)SQLite 查询中的“UNION”更改为“UNION ALL”。 (2认同)

Ark*_*lar 10

正如上面在 Tronic 的评论中提到的,可以通过键盘组合直接调用 OOM-killer(内存不足杀手)SysRq- F

SysRqkey 通常组合在PrtSc键盘上的 key 中。

OOM-killer 杀死一些进程(-es),系统再次响应。默认情况下可能未启用对 OOM-killer 的直接访问,请查看此问题以了解如何检查其状态和/或启用它。

PS:这对我帮助很大。我同意这样的观点,如果它是由 Chrome 或任何内存贪婪软件引起的,这是关于该问题的最有用的建议。但是您需要记住,OOM-killer 可能会杀死一些非常重要的进程,请谨慎使用。


Car*_*lez 8

你可以使用一个像earlyoom这样的守护进程来检查Swap和可用的RAM,你可以配置你想要有多少内存可用,RAM和SWAP,然后如果这个阈值发生,它会杀死最大的内存吞噬者,通常是有罪的吞噬者,如果您愿意,您还可以有一个例外列表。


Dan*_*scu 6

这是自 2007 年以来已知的错误 - 请参阅高内存使用率时系统冻结

在这种情况下,Windows 会显示一个对话框,警告用户关闭一个或多个应用程序。

  • @JonathanNeufeld:正确。我指出,与 Linux 不同,Windows 以更加用户友好的方式处理此问题。 (4认同)

Ant*_*des 0

这是特别难以预防的事情。这是因为内核开始交换。一种解决方案是关闭交换。当系统内存不足时,内核不会开始交换,而是会杀死一些进程;通常它会选择正确的进程来杀死,但无论如何,杀死随机进程比让系统无响应要好。

对于服务器来说,这可能是一个特别好的解决方案,因为服务器通常有足够的 RAM,当它们开始使用交换空间时,无论如何都意味着出现了问题。然而,台式机通常需要交换空间,所以我认为对于台式机没有好的解决方案。我经常关闭服务器中的交换空间,特别是当怀疑存在内存泄漏时。

  • 不管有没有交换,在 OOM 杀手自动运行之前它仍然会冻结。这确实是一个应该修复的内核错误(即在删除所有磁盘缓存之前先运行 OOM Killer)。不幸的是,内核开发人员和许多其他人没有看到这个问题。禁用/启用交换、购买更多 RAM、运行更少进程、设置限制等常见建议并不能解决内核的低内存处理问题。同时,我建议在系统死机时手动运行 OOM Killer (SysRq-F),因为这样可以更快地恢复。 (15认同)
  • 在任何系统上关闭交换都是一个坏主意,因为它不允许交换出未使用的页面以及用于磁盘缓存的可用空间。当存在内存泄漏时尤其如此。 (4认同)
  • 关闭交换后,系统仍然会因分页而变慢。它只会疯狂地分页干净页面而不是脏页面。(因为,如果没有交换,它永远无法驱逐脏页,所以它总是必须驱逐干净的页。) (2认同)