为什么即使我有足够的空闲 RAM 也要使用交换?

Mys*_*rio 248 swap kernel memory-usage

我认为交换的全部本质是在 RAM 已满时充当临时存储安全网,但即使有时我有多达 3GB 的空闲 RAM,我的交换分区也一直在使用。这是正常的吗?

jpe*_*sen 220

您可以尝试更改“swappiness”值:

来自Ubuntu 的 Swap FAQ

什么是swappiness,我该如何改变它?

swappiness 参数控制内核将进程从物理内存移到交换磁盘上的趋势。由于磁盘比 RAM 慢得多,如果进程过于频繁地移出内存,这可能会导致系统和应用程序的响应时间变慢。

  1. swappiness 的值可以在 0 到 100 之间

  2. swappiness=0 告诉内核尽可能长时间地避免将进程交换出物理内存。对于内核版本 3.5 和更新版本,它禁用了 swappiness。

  3. swappiness=100 告诉内核主动从物理内存中交换进程并将它们移动到交换缓存

Ubuntu 中的默认设置是 swappiness=60。减少 swappiness 的默认值可能会提高典型 Ubuntu 桌面安装的整体性能。建议使用 swappiness=10 的值,但可以随意尝试。注意:Ubuntu 服务器安装对桌面系统有不同的性能要求,默认值 60 可能更合适。

检查 swappiness 值

cat /proc/sys/vm/swappiness
Run Code Online (Sandbox Code Playgroud)

更改swappiness值 可以使用swappiness值为10的临时更改(重新启动时丢失)

sudo sysctl vm.swappiness=10
Run Code Online (Sandbox Code Playgroud)

要永久更改,请使用您喜欢的编辑器编辑配置文件:

gksudo gedit /etc/sysctl.conf
Run Code Online (Sandbox Code Playgroud)

搜索 vm.swappiness 并根据需要更改其值。如果 vm.swappiness 不存在,请将其添加到文件末尾,如下所示:

vm.swappiness=10
Run Code Online (Sandbox Code Playgroud)

保存文件并重新启动。

sudo sysctl --load=/etc/sysctl.conf编辑文件后运行以应用更改

您也可以查看:https : //askubuntu.com/a/103916/54187

  • @SimonRichter 是的,就是这个想法。不过,在现代系统上,60 的 Swappiness 可能过于激进,因为这意味着当您仍有几场可用内存时,您就开始换出。 (7认同)

tho*_*ter 120

你的问题有几个不同的方面。

首先,您对“免费”的定义是什么。它实际上并不像在 Linux(或任何现代操作系统)中听起来那么简单。

Linux 如何使用 RAM(非常简化)

每个应用程序都可以使用您的一些内存。Linux 使用所有其他未被占用的内存(最后几 Mb 除外)作为“缓存”。这包括页面缓存、inode 缓存等。这是一件好事 - 它有助于加快堆的速度。缓存可以极大地加快写入磁盘和读取磁盘的速度。

理想情况下,您有足够的内存供所有应用程序使用,并且还有数百 Mb 可用于缓存。在这种情况下,只要您的应用程序不增加它们的内存使用量并且系统没有努力获得足够的缓存空间,就不需要任何交换。

一旦应用程序要求更多的 RAM,它就会进入缓存使用的一些空间,从而缩小缓存。取消分配缓存既便宜又简单,可以实时完成——缓存中的所有内容要么只是磁盘上已有内容的第二个副本,因此可以立即取消分配,或者我们会这样做无论如何,必须在接下来的几秒钟内刷新到磁盘。

这不是 Linux 特有的情况——所有现代操作系统都以这种方式工作。不同的操作系统可能只是以不同的方式报告可用 RAM:有些将缓存作为他们认为“免费”的一部分,有些则可能没有。

当您谈论空闲 RAM 时,包括缓存更有意义,因为它实际上是免费的 - 如果任何应用程序请求它,它就可用。在 Linux 上,该free命令以两种方式报告 - 第一行包括已用 RAM 列中的缓存,第二行包括空闲列中的缓存(和缓冲区)。

Linux 如何使用交换(更简化)

一旦您用完足够的内存而没有足够的空间用于平滑运行的缓存,Linux 可能会决定从 RAM 中重新分配一些未使用的应用程序内存以进行交换。

它没有根据明确的截止日期来执行此操作。不像你达到一定比例的分配然后 Linux 开始交换。它有一个相当“模糊”的算法。它考虑了很多事情,最好用“内存分配有多大压力”来描述。如果分配新内存有很大的“压力”,那么它会增加一些被交换以腾出更多空间的机会。如果“压力”较小,那么这些机会就会减少。

您的系统具有“swappiness”设置,可帮助您调整“压力”的计算方式。通常根本不建议更改此设置,我也不建议您更改它。交换总体上是一件非常好的事情 - 尽管有一些边缘情况会损害性能,但如果您查看整体系统性能,这对广泛的任务来说是一个净收益。如果你减少swappiness,你会让缓存内存量比其他情况下收缩更多一点,即使它可能真的很有用。对于您在交换时遇到的任何问题,这是否是一个足够好的权衡取决于您。你应该知道你在做什么,仅此而已。

有一种众所周知的情况,即交换确实会损害桌面系统上的感知性能,这就是应用程序在长时间闲置并且后台进程 IO 繁重(例如隔夜备份)运行。这是一个非常明显的缓慢,但不足以证明完全关闭交换是合理的,并且在任何操作系统中都很难防止。关闭交换,备份/病毒扫描后的这种初始缓慢可能不会发生,但系统可能整天运行速度会慢一点。这也不是仅限于 Linux 的情况。

在选择要交换到磁盘的内容时,系统会尝试选择实际未使用的内存 - 读取或写入。它有一个非常简单的算法来计算这个,在大多数情况下选择得很好。

如果您的系统拥有大量 RAM(在撰写本文时,对于典型的 Linux 发行版而言,8GB 是一个巨大的数量),那么您将很少遇到需要交换的情况。您甚至可以尝试关闭交换。我从不建议这样做,只是因为您永远不知道更多 RAM 何时可以使您免于某些应用程序崩溃。但是如果你知道你不需要它,你就可以做到。

但是交换如何加速我的系统?交换不会减慢速度吗?

将数据从 RAM 传输到交换的行为是一个缓慢的操作,但只有在内核非常确定整体收益大于此时才会执行。例如,如果您的应用程序内存已经上升到几乎没有缓存可用并且您的 I/O 非常低效因此,您实际上可以通过释放一些内存来提高系统的速度,即使在交换数据以释放数据的初始费用之后。

这也是不得已而为之应该将应用程序实际上要求比你实际拥有的内存。在这种情况下,交换是必要的,以防止内存不足的情况,这通常会导致应用程序崩溃或不得不被强行杀死。

交换仅与系统性能不佳的时间有关,因为它发生在可用 RAM 用完时,即使您没有交换,这也会降低系统速度(或使其不稳定)。因此,为了简化事情,交换发生是因为您的系统陷入困境,而不是相反。

一旦数据在交换中,它什么时候再次出来?

从交换区传输数据(至少对于传统硬盘而言)与将数据放入交换区一样耗时。因此可以理解,您的内核将同样不愿意从交换中删除数据,特别是如果它实际上没有被使用(即读取或写入)。如果你在交换数据,并且它没有被使用,那么它实际上是一件好事,它仍然是交换,因为它留下了,其他的东西更多的内存被使用,有可能加快你的系统。

  • +1详细解释。我也喜欢在我的电脑上保持 2GiB 交换。如果出现问题 - 内存泄漏等,那么您可以看到交换上升并在内存不足发生之前查找问题。它是一个安全网,也是一个性能工具。 (7认同)
  • 在我的上网本上,只有 2GB RAM,我保留了 4GB 交换空间。这是因为我对上网本的使用超出了其预期用途,而且我的程序经常需要超过 2GB 的内存。由于 Linux 在内存不足的情况下表现得很差,所以我更喜欢有一个大的安全网。而且我有足够的磁盘空间。 (3认同)
  • @neon_overload:我应该注意到,根据惠普的说法,我的上网本的最大 RAM 是 1GB。我现在有 2GB 空间,互联网资源表明 2GB 是实际的最大值。因此需要这些类型的变通方法。 (2认同)
  • @thomasrutter:对于大型服务器,您的答案有何变化,我的一个有 1TB(是 1TB)的内存,但仍在使用交换;您会推荐什么交换设置和什么大小的交换分区? (2认同)

Sco*_*nce 30

设置 swappiness 值并不适用于所有情况。如果它对你有用,那就太好了。如果没有,我已经编写了一个脚本,通过关闭并重新打开它来定期清除交换。

如果您不小心,切换交换有点冒险。如果你没有足够的可用内存来保存所有的RAM加上一切都在交换,试图禁用交换会导致系统停止响应。我的脚本首先检查是否有足够的可用 RAM(这需要一些操作,因为实际可用 RAM 量与free报告为可用的不同),然后仅在有时切换交换。但是,如果您的 RAM 有点不足,请不要在脚本运行时启动另一个主要进程。这里是:

#!/bin/bash

# Make sure that all text is parsed in the same language
export LC_MESSAGES=en_US.UTF-8
export LC_COLLATE=en_US.UTF-8
export LANG=en_US.utf8
export LANGUAGE=en_US:en
export LC_CTYPE=en_US.UTF-8

# Calculate how much memory and swap is free
free_data="$(free)"
mem_data="$(echo "$free_data" | grep 'Mem:')"
free_mem="$(echo "$mem_data" | awk '{print $4}')"
buffers="$(echo "$mem_data" | awk '{print $6}')"
cache="$(echo "$mem_data" | awk '{print $7}')"
total_free=$((free_mem + buffers + cache))
used_swap="$(echo "$free_data" | grep 'Swap:' | awk '{print $3}')"

echo -e "Free memory:\t$total_free kB ($((total_free / 1024)) MB)\nUsed swap:\t$used_swap kB ($((used_swap / 1024)) MB)"

# Do the work
if [[ $used_swap -eq 0 ]]; then
    echo "Congratulations! No swap is in use."
elif [[ $used_swap -lt $total_free ]]; then
    echo "Freeing swap..."
    swapoff -a
    swapon -a
else
    echo "Not enough free memory. Exiting."
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)

您必须以 root 身份运行此脚本(例如,使用sudo)。这个脚本不会让你的系统无响应;如果您的 RAM 不足,它将拒绝切换交换。我已经使用这个脚本将近五年没有问题了。

  • 如果某些内容已移至交换区并且仍保留在交换区中,这通常是一件好事 - 这意味着数据实际上并未被使用,并且会释放一些 RAM 用于其他内容,从而可能提高速度。是什么让您相信这些数据不应该在交换中,而应该占用更有价值的 RAM?通常内核非常擅长知道哪些是未使用的,哪些可以安全地保留在交换中以释放 RAM。 (6认同)
  • 当然,但这并没有解决释放内存后要做什么的问题,尽管现在有足够的可用内存,但东西仍在交换中。内核不会在需要之前将其从交换中拉出,这可能会导致系统响应性出现重大问题。(考虑一下系统菜单何时全部换出:直到您单击菜单按钮它才会重新换回,这意味着您必须等待一段时间才能弹出菜单。)这就是手动将其拉出的原因适时交换可以提高系统响应能力。 (2认同)

小智 9

我编辑了 Scott Severance 的脚本以匹配已经包含总可用内存字段的免费版本的新版本。

#!/bin/bash

free_mem="$(free | grep 'Mem:' | awk '{print $7}')"
used_swap="$(free | grep 'Swap:' | awk '{print $3}')"

echo -e "Free memory:\t$free_mem kB ($((free_mem / 1024)) MiB)\nUsed swap:\t$used_swap kB ($((used_swap / 1024)) MiB)"
if [[ $used_swap -eq 0 ]]; then
    echo "Congratulations! No swap is in use."
elif [[ $used_swap -lt $free_mem ]]; then
    echo "Freeing swap..."
    sudo swapoff -a
    sudo swapon -a
else
    echo "Not enough free memory. Exiting."
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)


小智 5

通常交换在现在的系统上仍然未使用。根据我的经验,长时间运行而没有密集操作的进程被 linux 转移到交换。
它使一些受影响的程序运行缓慢。
如果你有大量的RAM的自由,你可以通过运行命令切换交换关闭:
swapoff -av(你需要sudo为它的权利。)
如果你不喜欢掉了,你可以打开它,使用对称的命令:
swapon -av(再次sudo需要)。

  • 完全关闭交换是矫枉过正,因为 swapiness=0 做同样的事情,但更安全(如果你*做*最终在内存中得到太多东西,它会在交换中抛出一些东西)。 (13认同)

Bil*_*hor 5

一旦交换被用于程序,它往往会在程序的生命周期内保持映射状态。许多程序都有很少使用的代码(和数据)。内存一旦被换出,就不太可能被换入。

将这些页面强制放入内存的一种方法是关闭交换设备。如果有两个,您可以关闭其中一个,然后重新打开,然后关闭第二个。如果确实需要交换,它将在设备之间移动。您可以关闭交换设备(或文件),但如果您确实需要交换空间,则可能会发生剧烈的事情。

除了内存中的正常内容之外,tempfs 还使用交换空间,并且会像其他内存一样进行交换。如果您运行需要大量临时磁盘的程序,则可能会强制换出页面。创建后的临时文件可能在几分钟后不再使用,并且是移动到交换设备的良好候选者。

在紧要关头,您可以使用文件作为交换设备。如果您暂时需要额外的交换空间,这非常有用。