创建一个每小时清空交换的 cron 脚本是一个坏主意吗?

Yva*_*aka 28 cron swap

多年来,我的小型 Ubuntu 配置一直遇到同样的问题:使用的交换空间随着时间的推移而增加。我的印象是,这主要是因为即使有足够的空间,分配的内存也永远不会返回到 RAM,除非用户操作如禁用交换。

我做了一个简短的cron命令来自动化这个,我有很好的结果:

#! /bin/sh

echo "* */1 * * * root swapoff -a && swapon -a" >> /etc/crontab
Run Code Online (Sandbox Code Playgroud)

但是因为它更像是一个技巧而不是这个问题的真正解决方案,我想知道它可能是一个坏主意的潜在原因,或者我如何改进这个脚本以使其更聪明一点?

Rin*_*ind 51

像这样使用它:是的,不好。在关闭交换之前,您确实需要检查是否有足够的可用内存。请参阅https://askubuntu.com/a/90399/15811以获得更好的版本。

另外:你确定吗?分配的交换并不意味着交换被使用。命令vmstat、列si(换入)和so(换出)。如果这些仍然为 0,您就会遇到另一个问题。根据我的经验,swap 很少使用,您可能不会使用它,认为它不会清空它,但没有什么可清空的。

  • 为了详细说明而不写我自己的答案,交换使用量随着时间的推移而增长**根本不是一件坏事**。这意味着内核正在慢慢找出消耗内存的垃圾**永远不会被使用**并将其移出以交换,以便内存可以用于真正帮助您的事情(例如能够保留更多fs 数据缓存,因此它不必不断丢弃它并从磁盘重新读取它)。 (5认同)
  • 等等什么?如果没有足够的内存让 swapoff 成功,swapoff 首先被 OOM 杀手杀死。是的,他们实际上对其进行了硬编码(它通过系统调用进行检查)。 (3认同)

mur*_*uru 42

我会说这是一个坏主意。如果您认为您有空闲内存并且一个活动进程没有从交换区移动到 RAM,那么要么您没有您认为的那么多空闲内存,要么该进程没有您认为的那么活跃是。

如果活动进程继续被交换,您应该修复导致内存压力的任何问题。如果它不是一个活跃的过程,那有什么大不了的?

  • 我有时会遇到一些问题,我杀死了一个内存泄漏的进程(这迫使其他所有东西都进入交换),让我使用了大约 10% 的 RAM……但是所有正在运行的程序都处于交换状态,直到我再次访问它们。因此,每次您触摸某物时,都会有两秒钟的延迟。我可以看到 OP 的来源,并且自动完成它会很好,但这不是正确的方法。 (3认同)

Sim*_*ter 35

这是个坏主意。

内核在物理内存接近满之前就开始复制(不移动)数据到交换区,因为如果某个进程需要大量内存,则可以立即重用交换区中已经有有效副本的任何页面,而无需再次写入到磁盘。

通常,这种情况主要发生在很长时间没有被访问的页面上,这是一个很好的指标,表明它们不太可能很快被访问。

如果您明确丢弃副本,则不会带来任何好处,因为数据仍然存在于 RAM 中,但是当某些进程想要分配大量内存并且交换变得必要时,可能会降低您的速度。

一旦物理内存已满 50% 以上,内核也将始终使用交换空间,因此即使您安装了足够的内存,这些数字也不会为零。

  • *总是*:我认为你假设 `/proc/sys/vm/swappiness` 保留为它的默认值 `70`,这对服务器有好处,并且相当积极地从没有的进程中分页出脏页触摸它们一段时间以腾出更多页面缓存的空间。这通常对台式机不利,因为 alt-tab 可能会变慢。 (4认同)

all*_*llo 22

这是一个坏主意。如果这有用,Linux 内核会以这种方式实现它。我不相信有理由更改多个调整参数,因为这样一个简单的 shell 脚本很可能并不比内核开发人员的算法更聪明。

你基本上有两种情况:

  • 无论如何都不会使用交换空间中的进程。为什么要将它们拉回 RAM 中?
  • RAM 很少,因此它们会被换出,然后您将它们拉回 RAM。然后您的系统将尽快将它们再次放入交换区。

所以主要有两点:

  1. 首先,当 RAM 太少而无法一次运行所有程序时,您的系统会变慢。Swap 将帮助您运行更多程序,但不会快速切换到很少使用的程序,因为它可能会被换掉。没有交换可能会杀死很少使用的一个或发送当前使用的一个内存不足异常。
  2. 其次,交换是一件好事,交换中的东西也是如此,因为您有可用的 RAM,但您目前并没有使用任何程序。

尽管太多程序不会出现内存不足的问题,但有些程序可能会根据当前空闲 RAM 分配内存(也许您的浏览器会使用更多内存缓存,您可以更快地浏览)并且内核可以使用空闲 RAM 进行磁盘缓存和类似的优化。当您强制交换为空时,内核将删除其读取缓存,例如启动一个新的 Firefox 实例将比 Firefox 仍在磁盘缓存中时花费更长的时间。

如果要调整内核的行为,请参阅swappiness 参数

@peter-cordes 提供了两个额外的资源:

如果您真的想要空交换,则可以永久关闭交换。我不明白为什么将它打开一个小时然后清空它比没有交换有优势。


小智 5

您可以通过告诉内核释放缓存来获得相同的结果:

echo 3 > /proc/sys/vm/drop_caches
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以避免可能出现内存不足的短暂时刻,并让内核决定哪些是必要的,哪些可以丢弃。