Linux 在内存不足时挂起

Linux 在内存不足时挂起

当我的机器内存不足时,我遇到了意外的行为。

我有一台 Intel i7-6700,32GB RAM,运行的是 Arch Linux,内核是 vanilla 4.14.8。SSD 磁盘上的加密 LVM 卷上有 32GB 交换空间。

在正常运行期间,我运行几个 QEMU/KVM 客户机以及其他东西(XFCE、Firefox 等)。正常内存使用率约为 20-30%,几乎没有交换。

但是当我运行一些内存密集型任务(例如7za a -md=29压缩大型文件)时,当内存使用率达到 100% 时,系统会挂起/冻结。键盘和鼠标完全停止响应,显示器冻结,磁盘活动停止,并且与机器的任何 TCP 连接都会在 SYN 阶段挂起。从这种情况中恢复的唯一方法是关闭机器的电源循环。

在挂起之前,可以看到几乎没有使用任何交换空间。当然,交换已启用,并且我没有使用任何与内存相关的特定 sysctl 设置(特别是,我的 vm.swappiness 的默认值为 60)。

我不明白的是:

  • 为什么内核不使用交换空间?
  • 为什么内存耗尽时 oom-killer 不会启动?

我不是内核专家,但据我所知,系统不应该在内存不足时冻结/挂起。我希望看到以下内容:

  • 当有可用的交换空间时,在内存和交换都被消耗之前(在我的情况下是 64G),不应该终止任何进程。
  • 7za即使没有交换,当内存耗尽时,oom-killer 也会终止
  • 即使没有上述两者,任何试图分配超过可用内存的进程都应该出现错误并正常失败。

因此,实际上有 3 种独立的机制可以防止内存耗尽,但它们似乎都失败了。我意识到可能存在一些我不知道的细微问题(例如客户虚拟机中的内存膨胀、锁定内存等),但我真的想不出任何可以解释我所看到的行为的东西。

有人能解释一下这里发生了什么以及为什么吗?我只是错过了什么吗?我可以做些什么来确保不会挂起吗?

编辑:

我进行了一些差异测试并发现:

  • LVM 卷上的加密交换 => 机器冻结。
  • 分区上的加密交换 => 一切正常(交换按预期使用,机器不会冻结)。

问题似乎与 LVM 有关。我在两种情况下都使用了相同的物理分区,因此它也与磁盘无关。在测试期间,我将 vm.swappiness 保留为 60(默认值)。

顺便提一下 - 在一次特定测试中,我注意到在 htop 中,在机器冻结之前,交换栏中出现了一个“缺口”。因此内核实际上开始使用交换,但只持续了大约 3 秒钟。

该问题应该很容易重现。

更新:

对于任何关注此事的人,我确定问题出在 LVM 上使用交换空间(无论是否加密)。这是在 4.x 内核上测试的,我无法通过调整 sysctl 参数来避免此挂起。我目前没有关于 5.x 的信息。对我来说,这似乎是内核错误。

答案1

我见过类似的结果发生 - 但问题不在于内存不足;而是一个占用了根分区/卷空间的过程。

例如,通常这可能是对 /tmp 或 / 中的其他文件系统的过度写入。内核将交换出它可以交换的任何东西(虽然不多),以将未写入的内存存储在 RAM 缓冲区中。很快这将失败,一切都会停止。

通常情况下,您会收到发出的警告消息 - 但对于特别占用存储空间的进程,您可能不会看到它们。

相关内容