内容纲要

Linux关闭swap时遇到 Cannot allocate memory 错误

my-linux:~ # swapoff -a
swapoff: /dev/sda1: swapoff failed: Cannot allocate memory

swap分区关闭

准备调整Linux下的swap分区的使用率。

在Linux下执行 swapoff -a -v报如下错误:

swapoff: /dev/sda1: swapoff failed: Cannot allocate memory

上述错误原因分析:

  从上述的信息可以看出,当前Linux系统swap设备为/dev/sda1,如果当前改交换分区使用的容量大于系统当前剩余的内存,就会报这个错误,因为在关闭交换分区的时候,需要把分区的数据全部写入到内存,如果内存容量不足,就会导致这个错误。

解决:

方法1:释放内存缓存

# sync ; echo 3 > /proc/sys/vm/drop_caches  #先把内存数据回写到磁盘,然后释放内存缓存

drop_caches接受的参数是123,分别清空pagecache、slab对象、pagecahce和slab对象

https://github.com/torvalds/linux/blob/master/Documentation/sysctl/vm.txt 可以找到对该文件参数的解释:

drop_caches

Writing to this will cause the kernel to drop clean caches, as well as
reclaimable slab objects like dentries and inodes.  Once dropped, their
memory becomes free.

To free pagecache:
    echo 1 > /proc/sys/vm/drop_caches
To free reclaimable slab objects (includes dentries and inodes):
    echo 2 > /proc/sys/vm/drop_caches
To free slab objects and pagecache:
    echo 3 > /proc/sys/vm/drop_caches

dirty状态的内存缓存不会被释放,如果要释放尽可能多的内存缓存,先执行命令sync,减少dirty状态的内存缓存。如果要disable,输入参数4,注意0不被接受:

上述方法可能不会成功,当你的swap分区使用太多的时候。

方法2:允许内存overcommit

overcommit_memory用来控制“用户空间申请内存时,是否进行内存容量判断(overcommit判断)以及是否批准:

When this flag is 0, the kernel attempts to estimate the amount
of free memory left when userspace requests more memory.

When this flag is 1, the kernel pretends there is always enough
memory until it actually runs out.

When this flag is 2, the kernel uses a "never overcommit"
policy that attempts to prevent any overcommit of memory.
Note that user_reserve_kbytes affects this policy.

设置的值为2表示不允许overcommit,这时候如果停掉swap,那么可用内存减少,用户空间的内存申请就可能触发overcommit被拒绝。