我运行的是 Ubuntu 16.04.1 LTS,内核为 4.4.0-36。不过,我认为这并不重要,因为我在许多发行版/内核版本中都看到了可怕的内核行为。
考虑以下起点:
- 假设我的系统有 4GB 内存和 4GB 交换分区。
- 我正在运行一个带有 GNOME、浏览器和当前打开的 IDE 的桌面环境。
- 我正在做一些编程,在此过程中,我引入了一个错误,导致我的程序分配无限量的内存。
到目前为止一切顺利,这是我应该恢复的情况,对吗?这就是我的想即将发生:
- 我的操作系统意识到我编写的程序是恶意的并且行为不正确。
- 它杀死了我的程序,可能带有有用的调试或日志消息
- 我能够恢复我的活动
但这并不是默认安装的 Ubuntu 所发生的情况。发生的事情是这样的:
- 有缺陷的程序被允许“无限期”运行
- 最终,当所有物理内存耗尽时,系统开始交换。
- 随着有问题的程序占用越来越多的内存,我的桌面程序的所有页面都被推送到交换区。我的硬盘开始发出非常非常可怕的声音
- 我的用户界面变得完全没有响应。点击发生几分钟后就会被记录,鼠标移动通常会被忽略。
- 任何对机器的访问都会被有效地停止。这包括更改虚拟终端、通过虚拟终端登录和通过 SSH 登录。
- 如果我确实设法以某种方式杀死了有问题的程序,则并非一切都很好。离得很远。
- 所有用户界面和系统服务现在都已换出,并开始慢慢换回物理 RAM。我的硬盘此时仍然疯狂。
- 我的系统大约需要 0.5 - 1 小时才能“平静下来”。
在不按下重置按钮的情况下重新启动机器也需要很长时间。谁会想到像内存不足这样简单的事情就会导致如此灾难性的事件?
我有几个问题:
- 谁认为在桌面系统上使用交换是个好主意,为什么?
- 我应该简单地禁用交换吗?不这样做的理由是什么?
- 有比禁用交换更好的方法吗?例如,有没有办法限制与流氓程序的交换并将我的系统服务和用户界面保留在物理内存中?
答案1
您可以使用 限制交换、物理内存或两者cgroups
。更原始的方法是使用 ulimit,但现在 cgroup 已成为标准。 (我不会复制粘贴整个 cgroups 文档)使用 cgroups,您还可以指定层次结构中每个程序的 cpu 和磁盘 I/O 使用限制,以便您可以为重要任务设置更高的优先级。
答案2
您可能需要调整 swappiness sysctl,并将其设置为 1 或 0,以避免在内存耗尽时使用磁盘。