如何完全禁用交换?

如何完全禁用交换?

我使用的是Debian sid,硬盘格式化为ext4,运行在linux 3.1上

我记得在以前的linux版本上(可能是3.0之前),如果内存不足,并且没有启用交换,程序通常会崩溃。这非常适合我的环境:简单的网页浏览,无需关键操作。也就是说,如果我不小心遇到一个占用过多内存的不良网站,它只会崩溃,而不会导致我的终端无法使用。

但在我当前的设置中,计算机在后台因 I/O 吞吐量剧烈而挂起。 iotop 显示 kswapd0 是罪魁祸首,这意味着它是由于交换造成的。在用于swapon -s确定已启用的任何交换后,我曾经swapoff -a禁用所有交换,并swapon -s再次确认所有交换均已禁用。

然后我再次尝试最大化内存使用率。唉,我预期的行为并没有发生。相反,kswapd0 一遍又一遍地尝试交换 RAM,但由于没有交换空间而失败。因为它永远不会放弃,所以我的计算机被锁定在永久的 I/O 严重冻结中,这对我的磁盘健康状况不利。

我尝试做错了什么吗swapoff -a?为什么行为与以前不同(可能是 3.0 之前的时代)?

答案1

禁用交换不会达到您想要的效果。您仍然会获得剧烈的 I/O 吞吐量,但它将是干净页面而不是脏页面。

如果没有交换,系统会将干净(未修改)页面的缓存压缩到接近零,因为这些是它可以从物理内存中逐出的唯一页面。它只能通过将脏页(修改过的)写入交换区来从内存中驱逐脏页,如果没有交换区,它无法驱逐脏页。

当物理内存不足时,每个进程都必须从磁盘加载其代码页,因为它会逐出先前的进程代码页。结果将是交换子系统的剧烈颠簸和过多的工作。

这是一个非常重要原则的特例:对于一个设计良好的系统,你不能通过减少它的选择来让它运行得更好。 Linux是一个设计良好的系统。删除交换只会给它带来更少的选择,所以它的表现更糟也就不足为奇了。

答案2

比关闭交换(在内存不足时最多会导致随机进程被杀死)更好的解决方案是为从网络上获取数据的进程设置每个进程的数据段限制。这样,失控的浏览器就会达到极限并死掉,而不是导致整个系统变得无法使用。示例,来自 shell

(ulimit -d 400000; firefox) &

-d 之后的数字以千字节为单位。您应该在您的系统上进行试验,以选择最适合您的浏览习惯的值。括号导致创建子 shell; ulimit 命令仅影响该 shell 及其子 shell,将其影响与父 shell 隔离。

答案3

为了确保不使用交换区,最好防止在启动时添加任何交换区。根据系统的不同,可以通过禁用swap引导服务或仅注释掉 中的交换条目来完成此操作/etc/fstab

就您的挂断而言,stop()中的函数/etc/init.d/swap可能会提供线索:

stop()
{
       ebegin "Deactivating swap devices"

       # Try to unmount all tmpfs filesystems not in use, else a deadlock may
       # occure. As $RC_SVCDIR may also be tmpfs we cd to it to lock it
       cd "$RC_SVCDIR"
       umount -a -t tmpfs 2>/dev/null

       case "$RC_UNAME" in
               NetBSD|OpenBSD) swapctl -U -t noblk >/dev/null;;
               *)              swapoff -a >/dev/null;;
       esac
       eend 0
}

注意关于的部分僵局。你可以尝试umount -a -t tmpfs自己做关闭交换。


编辑:

也许,您也可以通过修改sysctl设置来实现您的目标(请参阅这个问题)。

答案4

在我的系统(debian sid 2016-11-15)上,我这样做了:

  1. 立即禁用交换:

    swapoff -a
    
  2. 注释带有交换分区的行/etc/fstab(您可能不需要这个,也许只有步骤 3 而没有步骤 2 对您有用)

    #### #UUID=c6ddbc95-3bb5-49e1-ab25-b1c505e5360c none            swap    sw              0       0
    
  3. 禁用 systemd 中交换的安装(注意,如果单元名称包含反斜杠字符,请将单元名称括在引号中):

    systemctl --type swap
    systemctl stop "dev-\x2da821.swap"
    systemctl mask "dev-\x2da821.swap"
    

这似乎可以解决问题。

相关内容