我已经通过设置禁用了内存过度使用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 并且没有使用交换区域上的任何页面,也可能会发生这种情况。这是拥有一个不会随机杀死应用程序的系统所付出的代价。
在您的情况下,您有足够的可用虚拟内存,但其中一部分被保留,因此需要存在一些交换区域,这意味着您无法删除后者。