当 overcommit_memory==2 时 swapoff 失败

当 overcommit_memory==2 时 swapoff 失败

我已经通过设置禁用了内存过度使用overcommit_memory=2。现在,当我尝试时swapoff,我收到此错误:

swapoff: /dev/sda5: swapoff 失败: 无法分配内存

但事实上我有0 MiB交换空间和大量可用内存!我尝试将其设置overcommit_ratio为 100,但没有改变任何内容。

如果我暂时设置overcommit_memory=0为默认,我可以成功swapoff,然后重新禁用过度使用。

为什么会有如此奇怪的行为?这是一个错误吗?


编辑正如评论中所问:

$ grep -E '^Mem|Commit' /proc/meminfo
MemTotal:        2044420 kB
MemFree:          751836 kB
CommitLimit:     4122112 kB
Committed_AS:    2752544 kB

答案1

正如@Mat 指出的那样,Commited_AS > MemTotal。换句话说,您已经分配了比实际拥有的内存更多的内存,因此如果您要禁用交换,您就已经过度使用了。因此,当您不允许过度提交时,在释放一些内存之前您无法禁用交换。

并非所有分配的内存实际上都是用过的,这就是为什么尽管分配了这么多内存,但仍然有一些可用内存。

答案2

这是一个非常常见的困惑。有几个概念只是松散相关。

  • 物理内存使用情况
  • 交换区使用情况
  • 虚拟内存预留
  • 虚拟内存分配

当进程分配内存(malloc 或类似)时,它所做的实际上是保留内存。默认情况下,Linux 会过度使用虚拟内存,因此不太关心保留,通常会成功返回。

当您第一次访问保留内存时,该内存必须由位于 RAM 或磁盘上的页面支持。

如果没有足够的 RAM 来容纳 RAM 上的所有访问的虚拟内存,系统就会开始分页(通常称为交换)并且性能会停滞。

如果进程保留的内存多于交换区和(部分)RAM 的总和,并且您的系统配置为不过度使用内存,则分配会失败。即使您有足够的可用 RAM 并且没有使用交换区域上的任何页面,也可能会发生这种情况。这是拥有一个不会随机杀死应用程序的系统所付出的代价。

在您的情况下,您有足够的可用虚拟内存,但其中一部分被保留,因此需要存在一些交换区域,这意味着您无法删除后者。

相关内容