当 RAM 中有足够多的可用空间时,为什么要使用交换?

Ste*_*fan 154 performance swap

使用交换空间而不是 RAM 会大大降低PC 的速度

那么为什么当我有足够多的可用 RAM 时,我的 Linux 系统 (Arch) 会使用交换区吗?

在下面查看我的 conky 输出:

输出

另外,这可能是我遇到的速度和系统响应问题的原因吗?

的输出free -m

$ free -m
             total       used       free     shared    buffers     cached
Mem:          1257       1004        252          0         51        778
-/+ buffers/cache:        174       1082
Swap:          502        144        357
Run Code Online (Sandbox Code Playgroud)

Mar*_*erg 114

可以通过设置以下值来配置此行为:

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

默认值为 60。将其设置为 0 表示在仍有剩余 RAM 时从不使用交换,而 100 表示尽快换出内存。

临时更改值(在重新启动时丢失):

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

要永久更改值,请编辑文件:

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

作为根(例如sudoedit /etc/sysctl.conf)并更改或添加(如果没有)该行:

vm.swappiness
Run Code Online (Sandbox Code Playgroud)

到所需的值 ( vm.swappiness=10)。如果此文件不存在(例如在 Arch Linux 中),则尝试/etc/sysctl.d/99-sysctl.conf代替。

关于用可用内存换出是好是坏一直存在一些争论,但Ubuntu 帮助确实建议桌面系统的值为 10。另请参阅有关CentOS 的 Digital Ocean 的教程

  • 请注意,减少swappiness*不一定*意味着性能或响应能力的提高。我已经看到有关*增加*swappiness 转化为更好的性能的报告。不要相信您阅读的任何不包含基准的内容,并检查基准是否使用与您相似的工作负载。 (29认同)

Ric*_*rri 113

即使仍有可用 RAM ,Linux 系统使用一些交换区也是正常的。Linux 内核将移动到交换很少使用的内存页面(例如,getty当您只使用 X11 时的实例,以及一些其他不活动的守护进程)。

只有当没有足够的可用 RAM 时,交换空间使用才会成为一个问题并且内核被迫不断地将内存页面移动到交换区并返回到 RAM,只是为了保持应用程序运行。在这种情况下,系统监视器应用程序将显示大量磁盘 I/O 活动。

相比之下,我的 Ubuntu 10.04 系统,有两个用户使用 X11 会话登录,都运行 GNOME 桌面,使用 ~600MB 的交换和 ~1GB 的 RAM(不包括缓冲区和 fs 缓存),所以我会说你的交换数据使用看起来很正常。

  • 通过换出不活动的程序,您有更多的内存用于文件缓存。这加快了速度。 (50认同)

Gil*_*il' 46

Linux 在 RAM 被填满之前开始交换。这样做是为了提高性能和响应能力:

  • 性能提高是因为有时 RAM 更适合用于磁盘缓存而不是存储程序内存。因此,最好将一段时间不活动的程序换掉,而将经常使用的文件保存在缓存中。

  • 通过在系统空闲时换出页面来提高响应能力,而不是在内存已满且某些程序正在运行并请求更多 RAM 来完成任务时。

当然,交换确实会降低系统速度——但交换的替代方案并不是不交换,而是拥有更多的 RAM 或使用更少的 RAM。


Anu*_*nha 21

这是一个旧帖子,但是,我仍然会冒昧地在这里发表我的想法。

从下往上,Linux 会先把内存分页(在 x86_64 系统上通常是每页 4K)。此后,创建虚拟内存,其映射是使用 MMU(内存管理单元)与物理内存完成的。

进程是从虚拟内存区分配内存的,所以请注意,当你看到/proc/meminfo时,你会看到VMalloc*作为虚拟内存的详细信息。

假设您有一个请求内存的进程(比如 300MB - 一个网络浏览器)。该进程将从虚拟内存中分配 300MB,但是,它没有必要进行内存映射(即映射到物理内存)。内存管理有“写时复制”的概念,也就是说,如果您的进程实际使用从虚拟内存分配的内存(即它在内存上进行一些写入),那么它才会被映射到物理内存。这有助于内核在多进程环境中有效地正常工作。

什么是缓存?

进程使用的大量内存是共享的。假设几乎所有进程都使用 glibc 库。当每个进程都可以访问相同的内存位置并完成工作时,在内存中保留多个 glibc 副本有什么意义。这些经常使用的资源保存在缓存中,以便当进程需要时,它们可以被引用到相同的内存位置。这有助于加快进程,因为从磁盘一次又一次地读取 glibc(等)会很耗时。

以上是针对共享库的说法,类似的情况也适用于文件读取。如果您第一次读取一个大文件(比如 100-200MB),会花费很多时间。但是,当您尝试再次执行相同的读取时,速度会更快。数据缓存在内存中,并没有对所有块进行重新读取。

什么是缓冲?

就缓冲区而言,当进程进行文件 I/O 时,它依赖内核的缓冲区将数据写入磁盘。进程,请求内核做这项工作。因此,内核代表进程将数据写入其“缓冲区”,并告诉进程写入已完成。以异步方式,内核将继续将此缓冲区中的数据同步到磁盘。这样,进程依靠内核选择正确的时间将数据同步到磁盘,并且进程可以继续工作。请记住,这是正常进程正在执行的一般 I/O。但是,需要确认 I/O 确实在磁盘上进行的专门进程可以使用其他机制在磁盘上进行 I/O。一些开源实用程序是 libaio。此外,还有一些方法可以对在您的进程上下文中打开的 FD 调用显式同步,

那么什么是页面错误呢?

考虑一个例子,当你启动一个进程(比如一个 web 浏览器)时,它的二进制文件大约为 300MB。但是,完整的 300MB 网络浏览器二进制文件不会立即开始工作。该过程在其代码中不断从函数移动到函数。如前所述,虚拟内存将消耗 300MB 然而,并非所有内存都映射到物理内存(RSS - 常驻内存会更少,请参阅顶部输出)。当代码执行到达某个点时,内存实际上并未物理映射,页面错误就会成为问题。内核会将此内存映射到物理内存,将内存页面与您的进程相关联。这种页面错误称为“次要页面错误”。类似地,当进程执行文件 I/O 时,会引发主要页面错误。

何时以及为何发生换出?

情况一:

结合上面的细节,让我们考虑一个场景,当大量内存变为内存映射时。现在一个进程启动,这需要内存。如上所述,内核将进行一些内存映射。但是,没有足够的物理 RAM 可用于映射内存。现在,内核将首先查看缓存,它将有一些未使用的旧内存页面。它会将这些页面刷新到一个单独的分区(称为 SWAP),释放一些页面,并将释放的页面映射到即将到来的新请求。由于磁盘写入比固态 RAM 慢得多,因此此过程需要大量时间,因此速度会变慢。

情况二:

假设您看到系统中有大量可用内存。即便如此,您也会看到发生了很多换出。可能存在内存碎片问题。考虑一个进程,它需要内核提供 50MB 的连续内存。(记住连续)。显然,内核会将页面随机分配给不同的进程,并释放其中的一些。但是,当我们需要连续内存时,它将不得不寻找满足进程需求的块。如果它无法获得这样的内存,它将不得不交换一些旧的内存页面,然后分配连续的内存页面。即使在这种情况下也会发生掉期。从内核版本 2.6 及更高版本开始,此类碎片问题已大大减少。但是,如果系统运行时间长了,这样的问题还是会出现的。

请参阅此示例(vmstat 输出

2016-10-29 03:55:32 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
2016-10-29 03:55:32  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
2016-10-30 03:56:04 19 23 2914752 4692144 3344908 12162628 1660    1  8803 12701 4336 37487 14  7 40 38  0
2016-10-30 03:56:34  3 20 2889296 4977580 3345316 12026752 2109    2  8445 14665 4656 36294 12  7 46 34  0
2016-10-30 03:57:04  1 11 3418868 4939716 3347804 11536356  586 4744  2547  9535 3086 24450  6  3 59 33  0  <<<-----
2016-10-30 03:57:34  3 19 3456252 5449884 3348400 11489728 3291 13371  6407 17957 2997 22556  6  4 66 24  0
2016-10-30 03:58:04  7  6 4194500 5663580 3349552 10857424 2407 12240  3824 14560 2295 18237  4  2 65 29  0
2016-10-30 03:58:34  2 16 4203036 5986864 3348908 10838492 4601 16639  7219 18808 2575 21563  6  4 60 31  0
2016-10-30 03:59:04  3 14 4205652 6059196 3348760 10821448 6624 1597  9431  4357 1750 20471  6  2 60 31  0
2016-10-30 03:59:34  2 24 4206968 6053160 3348876 10777216 5221 2067 10106  7377 1731 19161  3  3 62 32  0
2016-10-30 04:00:04  0 13 4205172 6005084 3348932 10785896 6236 1609 10330  6264 1739 20348  4  2 67 26  0
2016-10-30 04:00:34  4 11 4206420 5996396 3348976 10770220 6554 1253 10382  4896 1964 42981 10  5 58 27  0
2016-10-30 04:01:04  6  4 4177176 5878852 3348988 10825840 8682  765 10126  2716 1731 32949  8  4 69 19  0
Run Code Online (Sandbox Code Playgroud)

@2016-10-30 03:57:04,我们看到仍有大量可用的可用 RAM。然而,即便如此,换出还是发生了。此时我们检查了进程树,我们没有看到任何需要如此大量内存(超过可用内存)的进程。明显的怀疑是上述情况 2。我们检查了上面的 buddyinfo 和 zoneinfo 日志(使用 echo m > /proc/sysrq-trigger 检查这些,输出进入 syslogs)。

对于我们的正常系统,区域信息的比较就是这样。下面还提到了缓存/空闲/低内存的图表

区域信息

掉期免费低免费

查看信息,很明显节点 0 和节点 1 正常存在内存碎片(节点是基于 NUMA 的机器,因此有多个节点(请参阅 numactl 以检查系统信息))。

内存碎片也是即使有空闲内存时交换使用量也会增加的一个原因。

  • 您应该澄清是否在您的“情况 2”中,要求苛刻的过程正在分配物理内存,这是一种不寻常的情况。大多数进程只处理碎片几乎无关的虚拟内存。您可能还想更好地解释如何从显示的数字和图表中断言内存碎片,因为乍一看并不明显。哦,顺便说一句,您实际上是在谈论 ** 连续** 内存,希望不是 ** 传染性** 内存 ;-) (2认同)

Huy*_*ens 5

拥有更多可用内存

就像每个人所说的那样,是的交换将帮助您摆脱未使用的内存,因此它可以帮助您获得更多可用内存。

冬眠

但是,swap 也可用于休眠,这在您拥有笔记本电脑或想要节省能源并在下班前将计算机置于休眠状态时非常有用。所以你可以在第二天早上更快地开始。

具有休眠功能是我们现在仍然看到的主要原因之一,建议至少具有用于交换的 RAM 大小。这样系统就可以将所有使用过的 RAM 放入交换区并进入休眠状态。

缺点

请注意,一旦交换,即使在关闭后也可以在交换中读取进程数据,除非交换已加密(当然)。

使用带休眠的加密交换并不适用于所有发行版。您需要使用一个恒定的加密密钥(某些设置在每次启动时随机生成交换空间加密密钥)和一个 initrd/initramfs 在恢复之前激活加密卷。