典型的计算机中有两种基本类型的内存。第一种类型是随机存取存储器 (RAM),用于在计算机 активно 使用数据和程序时存储它们。除非程序和数据存储在 RAM 中,否则计算机无法使用它们。RAM 是易失性存储器;也就是说,如果计算机关闭,存储在 RAM 中的数据将丢失。
硬盘是用于长期存储数据和程序的磁介质。磁介质是非易失性的;即使从计算机断开电源,存储在磁盘上的数据仍然存在。CPU(中央处理器)无法直接访问硬盘上的程序和数据;必须先将其复制到 RAM 中,CPU 才能在那里访问其编程指令以及要由这些指令操作的数据。在启动过程中,计算机将特定的操作系统程序(例如内核和 init 或 systemd)以及数据从硬盘复制到 RAM 中,计算机的处理器 CPU 在那里直接访问它们。
现代 Linux 系统中的第二种内存类型是交换空间。
交换空间
交换空间的主要功能是在实际 RAM 填满且需要更多空间时,用磁盘空间代替 RAM 内存。
例如,假设您有一个具有 8GB RAM 的计算机系统。如果您启动的程序没有填满 RAM,一切都很好,不需要交换。但是,假设您正在处理的电子表格在您添加更多行时增长,并且该电子表格加上正在运行的其他所有内容现在都填满了所有 RAM。在没有可用的交换空间的情况下,您将不得不停止处理电子表格,直到您可以通过关闭其他一些程序来释放一些有限的 RAM。
内核使用内存管理程序来检测内存块(也称为页),其中内容最近未使用过。内存管理程序将足够多的这些相对不常用的内存页交换到硬盘驱动器上的特殊分区,该分区专门用于“分页”或交换。这释放了 RAM 并为更多数据输入到电子表格中腾出空间。交换到硬盘驱动器的那些内存页由内核的内存管理代码跟踪,如果需要,可以分页回 RAM。
Linux 计算机中的内存总量是 RAM 加上交换空间,称为虚拟内存。
Linux 交换的类型
Linux 提供了两种类型的交换空间。默认情况下,大多数 Linux 安装都会创建交换分区,但也可以使用专门配置的文件作为交换文件。交换分区顾名思义,就是一个标准的磁盘分区,通过 mkswap
命令指定为交换空间。
如果没有可用于创建新交换分区的可用磁盘空间,或者在可以为交换空间创建逻辑卷的卷组中没有空间,则可以使用交换文件。这只是一个创建并预先分配到指定大小的常规文件。然后运行 mkswap
命令将其配置为交换空间。除非绝对必要,否则我不建议使用文件作为交换空间。
抖动
当总虚拟内存(包括 RAM 和交换空间)几乎满时,可能会发生抖动。系统花费大量时间在交换空间和 RAM 之间来回分页内存块,以至于几乎没有时间进行实际工作。这种情况的典型症状很明显:系统变得缓慢或完全无响应,并且硬盘驱动器活动指示灯几乎一直亮着。
如果您可以设法发出像 free
这样的命令来显示 CPU 负载和内存使用情况,您将看到 CPU 负载非常高,可能是系统中 CPU 核心数量的 30 到 40 倍。另一个症状是 RAM 和交换空间几乎都已完全分配。
事后,查看 SAR(系统活动报告)数据也可以显示这些症状。我在我工作的每个系统上都安装了 SAR,并将其用于修复后的取证分析。
多少交换空间是合适的?
许多年前,硬盘驱动器上应分配的交换空间量的经验法则是计算机中安装的 RAM 量的 2 倍(当然,那是在大多数计算机的 RAM 以 KB 或 MB 为单位进行测量时)。因此,如果计算机有 64KB 的 RAM,则 128KB 的交换分区将是最佳大小。该规则考虑了当时 RAM 大小通常很小以及为交换空间分配超过 2 倍 RAM 并不能提高性能的事实。对于超过两倍 RAM 的交换,大多数系统花费更多时间进行抖动,而不是实际执行有用的工作。
RAM 已成为一种廉价商品,如今大多数计算机的 RAM 容量都扩展到数十 GB。我的大多数较新的计算机至少有 8GB 的 RAM,一台有 32GB,而我的主要工作站有 64GB。我的旧计算机的 RAM 容量为 4 到 8 GB。
在处理具有大量 RAM 的计算机时,交换空间的限制性能因素远低于 2 倍乘数。Fedora 28 在线安装指南(可在 Fedora 安装指南 在线找到)定义了当前关于交换空间分配的想法。我在下面包含了该文档中的一些讨论和建议表。
下表提供了建议的交换分区大小,具体取决于系统中的 RAM 量以及您是否需要足够的内存供系统休眠。建议的交换分区大小在安装期间自动建立。但是,要允许休眠,您需要在自定义分区阶段编辑交换空间。
表 1:Fedora 文档中推荐的系统交换空间
系统 RAM 容量 |
建议的交换空间 |
建议的带休眠的交换空间 |
---|---|---|
小于 2 GB |
RAM 容量的 2 倍 |
RAM 容量的 3 倍 |
2 GB - 8 GB |
等于 RAM 容量 |
RAM 容量的 2 倍 |
8 GB - 64 GB |
RAM 容量的 0.5 倍 |
RAM 容量的 1.5 倍 |
大于 64 GB |
取决于工作负载 |
不建议休眠 |
在上面列出的每个范围之间的边界(例如,具有 2 GB、8 GB 或 64 GB 系统 RAM 的系统),请自行决定选择的交换空间和休眠支持。如果您的系统资源允许,增加交换空间可能会带来更好的性能。
当然,大多数 Linux 管理员对合适的交换空间量都有自己的想法,以及几乎所有其他方面。下表 2 包含我根据自己在多种环境中的个人经验提出的建议。这些建议可能不适合您,但与表 1 一样,它们可能会帮助您入门。
表 2:作者推荐的系统交换空间
RAM 容量 |
建议的交换空间 |
---|---|
≤ 2GB |
2 倍 RAM |
2GB – 8GB |
>= RAM |
>8GB |
8GB |
两个表中的一个考虑因素是,随着 RAM 容量的增加,超过某个点后,添加更多交换空间只会导致抖动,甚至在交换空间接近填满之前就抖动了。如果在遵循这些建议的同时,您的虚拟内存太少,则应尽可能添加更多 RAM,而不是更多交换空间。与所有影响系统性能的建议一样,请使用最适合您特定环境的方法。这将需要时间和精力来试验并根据 Linux 环境中的条件进行更改。
向非 LVM 磁盘环境添加更多交换空间
由于已安装 Linux 的主机上对交换空间的需求不断变化,因此可能需要修改为系统定义的交换空间量。此过程可用于需要增加交换空间量的任何一般情况。它假设有足够的可用磁盘空间。此过程还假设磁盘已分区为“原始”EXT4 和交换分区,并且不使用逻辑卷管理 (LVM)。
要采取的基本步骤很简单
-
关闭现有交换空间。
-
创建所需大小的新交换分区。
-
重新读取分区表。
-
将分区配置为交换空间。
-
添加新分区到 /etc/fstab。
-
开启交换。
不需要重启。
为了安全起见,在关闭交换之前,您至少应确保没有应用程序正在运行并且没有交换空间正在使用。free
或 top
命令可以告诉您是否正在使用交换空间。为了更安全,您可以恢复到运行级别 1 或单用户模式。
使用关闭所有交换空间的命令关闭交换分区
$ swapoff -a
现在显示硬盘驱动器上的现有分区。
$ fdisk -l
这将显示每个驱动器上的当前分区表。按编号识别当前交换分区。
使用命令在交互模式下启动 fdisk
$ fdisk /dev/<device name>
例如
$ fdisk /dev/sda
此时,fdisk
是交互式的,并且仅在指定的磁盘驱动器上运行。
使用 fdisk p
子命令验证磁盘上是否有足够的可用空间来创建新的交换分区。硬盘驱动器上的空间以 512 字节块以及起始和结束柱面号表示,因此您可能需要进行一些数学运算来确定已分配分区之间和末尾的可用空间。
使用 n
子命令创建新的交换分区。fdisk 将询问您起始柱面。默认情况下,它选择编号最低的可用柱面。如果您想更改它,请输入起始柱面的编号。
现在,fdisk
命令允许您以多种格式输入分区的大小,包括最后一个柱面号或以字节、KB 或 MB 为单位的大小。输入 4000M,这将在新分区上提供大约 4GB 的空间(例如),然后按 Enter 键。
使用 p
子命令验证分区是否已按您指定的方式创建。请注意,除非您使用了结束柱面号,否则分区可能与您指定的完全不一样。fdisk
命令只能以整个柱面的增量分配磁盘空间,因此您的分区可能比您指定的略小或略大。如果分区不是您想要的,您可以删除它并重新创建它。
现在有必要指定新分区将是交换分区。子命令 t
允许您指定分区类型。因此,输入 t
,指定分区号,当它询问十六进制代码分区类型时,输入 82,即 Linux 交换分区类型,然后按 Enter 键。
当您对创建的分区感到满意时,请使用 w
子命令将新的分区表写入磁盘。fdisk
程序将在完成写入修订后的分区表后退出并返回到命令提示符。当 fdisk
完成写入新的分区表时,您可能会收到以下消息
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.
此时,您可以使用 partprobe
命令强制内核重新读取分区表,这样就不需要执行重新启动。
$ partprobe
现在使用命令 fdisk -l
列出分区,新的交换分区应在列出的分区中。确保新分区类型为“Linux swap”。
将需要修改 /etc/fstab 文件以指向新的交换分区。现有行可能如下所示
LABEL=SWAP-sdaX swap swap defaults 0 0
其中 X
是分区号。根据新交换分区的位置,添加一个类似的新行
/dev/sdaY swap swap defaults 0 0
确保使用正确的分区号。现在您可以执行创建交换分区的最后一步。使用 mkswap
命令将分区定义为交换分区。
$ mkswap /dev/sdaY
最后一步是使用以下命令开启交换
$ swapon -a
您的新交换分区现在与先前存在的交换分区一起联机。您可以使用 free
或 top
命令来验证这一点。
向 LVM 磁盘环境添加交换
如果您的磁盘设置使用 LVM,则更改交换空间将非常容易。同样,这假设在当前交换卷所在的卷组中有可用空间。默认情况下,LVM 环境中 Fedora Linux 的安装过程会将交换分区创建为逻辑卷。这使其变得容易,因为您可以简单地增加交换卷的大小。
以下是在 LVM 环境中增加交换空间量所需的步骤
-
关闭所有交换。
-
增加指定用于交换的逻辑卷的大小。
-
将调整大小的卷配置为交换空间。
-
开启交换。
首先,使用 lvs
命令(列出逻辑卷)验证交换是否存在并且是逻辑卷。
# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
home fedora_studentvm1 -wi-ao---- 2.00g
pool00 fedora_studentvm1 twi-aotz-- 2.00g 8.17 2.93
root fedora_studentvm1 Vwi-aotz-- 2.00g pool00 8.17
swap fedora_studentvm1 -wi-ao---- 8.00g
tmp fedora_studentvm1 -wi-ao---- 5.00g
usr fedora_studentvm1 -wi-ao---- 15.00g
var fedora_studentvm1 -wi-ao---- 10.00g
您可以看到当前的交换大小为 8GB。在本例中,我们想向此交换卷添加 2GB。首先,停止现有交换。如果正在使用交换空间,您可能必须终止正在运行的程序。
$ swapoff -a
现在增加逻辑卷的大小。
# lvextend -L +2G /dev/mapper/fedora_studentvm1-swap
Size of logical volume fedora_studentvm1/swap changed from 8.00 GiB (2048 extents) to 10.00 GiB (2560 extents).
Logical volume fedora_studentvm1/swap successfully resized.
运行 mkswap
命令将整个 10GB 分区转换为交换空间。
# mkswap /dev/mapper/fedora_studentvm1-swap
mkswap: /dev/mapper/fedora_studentvm1-swap: warning: wiping old swap signature.
Setting up swapspace version 1, size = 10 GiB (10737414144 bytes)
no label, UUID=3cc2bee0-e746-4b66-aa2d-1ea15ef1574a
重新开启交换。
# swapon -a
现在使用 list block devices 命令验证新的交换空间是否存在。同样,不需要重新启动。
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 60G 0 disk
|-sda1 8:1 0 1G 0 part /boot
`-sda2 8:2 0 59G 0 part
|-fedora_studentvm1-pool00_tmeta 253:0 0 4M 0 lvm
| `-fedora_studentvm1-pool00-tpool 253:2 0 2G 0 lvm
| |-fedora_studentvm1-root 253:3 0 2G 0 lvm /
| `-fedora_studentvm1-pool00 253:6 0 2G 0 lvm
|-fedora_studentvm1-pool00_tdata 253:1 0 2G 0 lvm
| `-fedora_studentvm1-pool00-tpool 253:2 0 2G 0 lvm
| |-fedora_studentvm1-root 253:3 0 2G 0 lvm /
| `-fedora_studentvm1-pool00 253:6 0 2G 0 lvm
|-fedora_studentvm1-swap 253:4 0 10G 0 lvm [SWAP]
|-fedora_studentvm1-usr 253:5 0 15G 0 lvm /usr
|-fedora_studentvm1-home 253:7 0 2G 0 lvm /home
|-fedora_studentvm1-var 253:8 0 10G 0 lvm /var
`-fedora_studentvm1-tmp 253:9 0 5G 0 lvm /tmp
sr0
您还可以使用 swapon -s
命令,或 top
、free
或其他几个命令来验证这一点。
# free
total used free shared buff/cache available
Mem: 4038808 382404 2754072 4152 902332 3404184
Swap: 10485756 0 10485756
请注意,不同的命令以不同的形式显示或要求输入设备特殊文件。在 /dev 目录中访问特定设备的方式有很多种。我的文章 Linux 中的设备管理 包含有关 /dev 目录及其内容的更多信息。
本文最初于 2018 年 9 月发布,并由编辑更新了其他信息。
5 条评论