什么是 Linux 上的交换性? (以及如何改变它)什么是 Linux 上的交换性? (以及如何改变它)什么是 Linux 上的交换性? (以及如何改变它)什么是 Linux 上的交换性? (以及如何改变它)
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

什么是 Linux 上的交换性? (以及如何改变它)

Linux swappiness 值与交换开始前使用了多少 RAM 无关。这是一个被广泛报道和广泛相信的错误。我们解释它到底是什么。

打破关于 Swapiness 的神话

交换是一种将随机存取存储器 (RAM) 中的数据写入硬盘上的特殊位置(交换分区或交换文件)以释放 RAM 的技术。

Linux 有一个称为 swappiness 值的设置。关于此设置控制的内容存在很多混淆。对 swappiness 最常见的错误描述是它为 RAM 使用设置了一个阈值,当使用的 RAM 量达到该阈值时,交换开始。

这是一个经常被重复的错误观念,现在已成为常识。如果(几乎)其他所有人都告诉你这正是 swappiness 的工作原理,那么当我们说它不是时你为什么要相信我们呢?

简单的。我们要证明这一点。

您的 RAM 被分成多个区域

Linux 不会将您的 RAM 视为一个大的同质内存池。它认为它被分成许多不同的区域,称为区域。您的计算机上存在哪些区域取决于它是 32 位还是 64 位。下面是对 x86 架构计算机上可能存在的区域的简单描述。

  • 直接内存访问 (DMA):这是低 16 MB 内存。该区域之所以得名,是因为很久以前,有些计算机只能对物理内存的这个区域进行直接内存访问。
  • Direct Memory Access 32:尽管名称如此,但 Direct Memory Access 32 (DMA32) 是仅在 64 位 Linux 中发现的区域。这是低 4 GB 的内存。在 32 位计算机上运行的 Linux 只能对这个数量的 RAM 执行 DMA(除非它们使用物理地址扩展 (PAE) 内核),这就是该区域得名的原因。虽然,在 32 位计算机上,它被称为 HighMem。
  • 正常:在 64 位计算机上,正常内存是 4GB(大约)以上的所有 RAM。在 32 位机器上,它是 16 MB 到 896 MB 之间的 RAM。
  • HighMem:这仅存在于 32 位 Linux 计算机上。它是 896 MB 以上的所有 RAM,包括在足够大的机器上 4 GB 以上的 RAM。

PAGESIZE 值

RAM 以固定大小的页为单位进行分配。该大小由内核在启动时通过检测计算机的体系结构来确定。通常,Linux 计算机上的页面大小为 4 KB。

您可以使用 getconf 命令查看您的页面大小:

getconf PAGESIZE

区域附加到节点

区域附加到节点。节点与中央处理单元 (CPU) 相关联。内核将尝试从与该 CPU 关联的节点为在该 CPU 上运行的进程分配内存。

节点绑定到 CPU 的概念允许混合内存类型安装在专业的多 CPU 计算机中,使用非统一内存访问架构。

这都是非常高端的。一般的 Linux 计算机将有一个节点,称为节点零。所有区域都将属于该节点。要查看计算机中的节点和区域,请查看 /proc/buddyinfo 文件。我们将使用 less 来做到这一点:

less /proc/buddyinfo

这是研究本文的 64 位计算机的输出:

Node 0, zone DMA   1  1  1  0  2  1  1  0  1  1  3
Node 0, zone DMA32 2 67 58 19  8  3  3  1  1  1 17

有一个节点,节点零。这台计算机只有 2 GB 的 RAM,因此没有“正常”区域。只有两个区域,DMA 和 DMA32。

每列代表特定大小的可用页面数。例如,对于 DMA32 区域,从左侧读取:

  • 2:有 2 个内存块,共 2^(0*PAGESIZE) 个内存块。
  • 67:有 67 of 2^(1*PAGE_SIZE) 内存块。
  • 58:2^(2*PAGESIZE) 个内存块中有 58 个可用。
  • 等等,一直到……
  • 17:有 17 of 2^(512*PAGESIZE) 块。

但实际上,我们查看此信息的唯一原因是查看节点和区域之间的关系。

文件页面和匿名页面

内存映射使用页表条目集来记录使用了哪些内存页以及用途。

内存映射可以是:

  • 文件支持:文件支持的映射包含从文件中读取的数据。它可以是任何类型的文件。需要注意的重要一点是,如果系统释放了这块内存并需要再次获取该数据,则可以再次从文件中读取。但是,如果内存中的数据已更改,则需要先将这些更改写入硬盘驱动器上的文件,然后才能释放内存。如果那没有发生,更改将会丢失。
  • 匿名:匿名内存是一种没有文件或设备支持的内存映射。这些页面可能包含程序动态请求的内存,以保存数据,或用于堆栈和堆之类的东西。因为这类数据背后没有文件,所以必须专门留出一个地方来存放匿名数据。那个地方就是交换分区或交换文件。在释放匿名页面之前写入匿名数据进行交换。
  • 设备支持:设备通过块设备文件寻址,这些文件可以被视为文件。可以从它们读取数据并向它们写入数据。设备支持的内存映射存储了来自设备的数据。
  • Shared:多个页表条目可以映射到 RAM 的同一页。通过任何映射访问内存位置将显示相同的数据。不同的进程可以通过更改这些共同监视的内存位置中的数据,以一种非常有效的方式相互通信。共享可写映射是实现高性能进程间通信的常用方法。
  • 写时复制:写时复制是一种惰性分配技术。如果请求已在内存中的资源副本,则通过返回到原始资源的映射来满足请求。如果“共享”资源的进程之一试图写入它,则资源必须真正复制到内存中以允许对新副本进行更改。因此内存分配仅在第一个写入命令时发生。

对于交换性,我们只需要关注列表中的前两个:文件页面和匿名页面。

交换性

以下是 GitHub 上 Linux 文档中对 swappiness 的描述:

<代码>\此控件用于定义内核将交换内存页面的积极程度(原文如此)。较高的值会增加积极性,较低的值会减少交换量。0 值指示内核在交换之前不要启动交换可用页面和文件备份页面的数量低于区域中的高水位线。

默认值为 60。\

这听起来像是 swappiness 会在强度上调高或调低 swap。有趣的是,它指出将 swappiness 设置为零并不会关闭交换。它指示内核在满足某些条件之前不要进行交换。但是交换仍然会发生。

让我们深入挖掘。以下是内核源代码文件 vmscan.c 中 vm_swappiness 的定义和默认值:

<代码>/*
* 从 0 .. 100。更高意味着更多 swappy。
*/
int vm_swappiness=60;

swappiness 值的范围可以从 0 到 100。同样,评论听起来确实像是 swappiness 值与发生多少交换有关,较高的数字会导致更多的交换。

在源代码文件中,我们可以看到一个名为 swappiness 的新变量被分配了一个值,该值由函数 mem_cgroup_swappiness() 返回。通过源代码的更多跟踪将显示此函数返回的值是 vm_swappiness。所以现在,变量 swappiness 设置为等于 vm_swappiness 设置的任何值。

int swappiness=mem_cgroup_swappiness(memcg);

在同一个源代码文件的更下方,我们看到:

<代码>/*
* swappiness 为 100 时,anonymous 和 file 具有相同的优先级。
* 这个扫描优先级本质上是IO成本的倒数。
*/
anon_prio=swappiness;
file_prio=200 - anon_prio;

那很有意思。 swappiness 派生出两个不同的值。 anon_prio 和 file_prio 变量保存这些值。一个增加,另一个减少,反之亦然。

Linux swappiness 值实际上设置了两个 值之间的比率。

黄金比例

如果内存被释放,文件页面保存的数据可以很容易地检索到。 Linux 可以再次读取该文件。如我们所见,如果文件数据在 RAM 中发生了更改,则必须先将这些更改写入文件,然后才能释放文件页。但是,无论哪种方式,都可以通过从文件中读取数据来重新填充 RAM 中的文件页。那么为什么要费心将这些页面添加到交换分区或交换文件中呢?如果您再次需要该数据,不妨从原始文件中读回,而不是从交换空间中的冗余副本中读回。所以文件页面不存储在交换空间中。它们被“存储”回原始文件中。

对于匿名页面,没有与内存中的值关联的基础文件。这些页面中的值是动态获得的。您不能简单地从文件中读回它们。可以恢复匿名页面内存值的唯一方法是在释放内存之前将数据存储在某个地方。这就是交换所拥有的。您将需要再次引用的匿名页面。

但请注意,对于文件页面和匿名页面,释放内存可能需要硬盘驱动器写入。如果文件页面数据或匿名页面数据自上次写入文件或交换后发生更改,则需要文件系统写入。要检索数据,需要读取文件系统。两种类型的页面回收都是昂贵的。试图通过最小化匿名页面的交换来减少硬盘输入和输出只会增加处理文件页面写入和读取文件所需的硬盘输入和输出量。

从最后一个代码片段可以看出,有两个变量。一种称为 file_prio 用于“文件优先级”,另一种称为 anon_prio 用于“匿名优先级”。

  • anon_prio 变量设置为 Linux 交换值。
  • file_prio 值设置为 200 减去 anon_prio 值。

这些变量包含协同工作的值。如果它们都设置为 100,则它们相等。对于任何其他值,anon_prio 将从 100 减少到 0,而 file_prio 将从 100 增加到 200。这两个值将输入一个复杂的算法,该算法确定 Linux 内核是否优先回收(释放)文件页面或匿名页面。

您可以将 file_prio 视为系统释放文件页面的意愿,将 anon_prio 视为系统释放匿名页面的意愿。这些值不会为 何时 将使用交换设置任何类型的触发器或阈值。那是在别处决定的。

但是,当需要释放内存时,回收和交换算法会考虑这两个变量以及它们之间的比率,以确定优先考虑释放哪些页面类型。这决定了相关的硬盘驱动器活动是处理文件页面的文件还是匿名页面的交换空间。

掉期何时真正切入?

我们已经确定 Linux swappiness 值设置了内存页面类型的首选项,这些内存页面将被扫描以进行潜在回收。这很好,但是某事必须决定 什么时候交换将被切入。

每个内存区域都有一个高水位线和一个低水位线。这些是系统派生值。它们是每个区域中 RAM 的百分比。这些值用作交换触发阈值。

要检查您的高水位线和低水位线,请使用以下命令查看 /proc/zoneinfo 文件:

less /proc/zoneinfo

每个区域都有一组以页为单位的内存值。以下是测试机器上 DMA32 区域的值。低水位线为 13966 页,高水位线为 16759 页:

  • 在正常运行条件下,当区域中的可用内存低于区域的低水位线时,交换算法开始扫描内存页面以寻找可以回收的内存,同时考虑 anon_prio 的相对值 和 file_prio。
  • 如果 Linux swappiness 值设置为零,则当文件页面和可用页面的组合值小于高水位线时发生交换。

所以你可以看到你不能使用 Linux swappiness 值来影响 swap 在 RAM 使用方面的行为。它只是不那样工作。

Swapiness应该设置成什么?

这取决于硬件、工作负载、硬盘驱动器类型以及您的计算机是台式机还是服务器。显然,这不会是一种适合所有类型设置的尺寸。

而且你必须记住,当你的内存空间用完时,交换不仅仅是用作释放 RAM 的机制。 Swap 是一个运行良好的系统的重要组成部分,没有它,Linux 就很难实现合理的内存管理。

更改 Linux swappiness 值会立即生效;你不需要重新启动。因此,您可以进行小幅调整并监控效果。理想情况下,您可以在几天内执行此操作,在计算机上进行不同类型的活动,以尝试找到最接近理想设置的设置。

这些是需要考虑的几点:

  • 尝试通过将 Linux swappiness 值设置为零来“禁用交换”只会将与交换相关的硬盘驱动器活动转移到与文件相关的硬盘驱动器活动。
  • 如果您有老化的机械硬盘驱动器,您可以尝试降低 Linux swappiness 值以远离匿名页面回收并减少交换分区变动。当然,当您调低一个设置时,另一个设置会增加。减少交换改动可能会增加文件系统改动。但是您的计算机可能更喜欢一种方法而不是另一种方法。真的,唯一确定的方法就是尝试看看。
  • 对于单一用途的服务器,例如数据库服务器,您可以从数据库软件的供应商那里获得指导。通常,这些应用程序有自己专门设计的文件缓存和内存管理例程,您最好依赖这些例程。软件提供商可能会根据机器规格和工作负载建议 Linux 交换值。
  • 对于硬件较新的普通桌面用户?保持原样。

如何设置 Linux Swappiness 值

在更改 swappiness 值之前,您需要知道它的当前值是多少。如果要减少一点点,问题是比什么少一点点?你可以用这个命令找出来:

cat /proc/sys/vm/swappiness

要配置 swappiness 值,请使用 sysctl 命令:

sudo sysctl vm.swappiness=45

新值立即使用,无需重新启动。

事实上,如果您重新启动,swappiness 值将返回到其默认值 60。当您完成试验并决定要使用的新值后,您可以通过将其添加到 /etc/sysctl.conf 文件。您可以使用您喜欢的任何编辑器。使用以下命令使用 nano 编辑器编辑文件:

sudo nano /etc/sysctl.conf

当 nano 打开时,滚动到文件底部并添加这一行。我们使用 35 作为永久交换值。您应该替换您希望使用的值。

vm.swappiness=35

要保存更改并退出 nano,请按“Ctrl+O”,按“Enter”,然后按“Ctrl+Z”。

内存管理很复杂

内存管理很复杂。这就是为什么对于普通用户来说,通常最好将其留给内核。

很容易认为您使用的 RAM 比实际多。 top 和 free 等实用程序可能会给人留下错误的印象。 Linux 会将空闲 RAM 用于其自身的各种用途,例如磁盘缓存。这人为地提高了“已用”内存数字并减少了“可用”内存数字。事实上,用作磁盘缓存的 RAM 被标记为“已用”和“可用”,因为它可以随时回收,而且速度非常快。

对于外行来说,swap 似乎不起作用,或者 swappiness 值需要更改。

一如既往,细节决定成败。或者,在这种情况下,守护进程。内核交换守护进程。

Linux Commands
Files tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc
Processes alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap
Networking netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld

RELATED: Best Linux Laptops for Developers and Enthusiasts

©2015-2025 艾丽卡 support@alaica.com