Swap

出自 Arch Linux 中文维基

本文介紹了GNU/Linux上的交換空間和分頁。它將教您如何創建或啟用交換分區或交換文件。

以下引用來自於關於 Linux Swap 空間:

Linux 將物理內存分為內存段,叫做頁面。交換是指內存頁面被複製到預先設定好的硬盤空間(叫做交換空間)的過程,目的是釋放這份內存頁面。物理內存和交換空間的總大小是可用的虛擬內存的總量。

swap 支持由 Linux 內核和來自 util-linux 軟件包的用戶空間實用程序提供。

交換空間[編輯 | 編輯原始碼]

交換空間可以是磁盤的一個分區,也可以是一個文件。用戶可以在安裝時或安裝後的任何時候創建交換空間。交換空間有兩種用途:第一,是將虛擬內存擴大到超過已安裝的物理內存(RAM)的容量;第二,是用於 suspend-to-disk 支持。

使用swap擴展您的虛擬內存是否有好處取決與您的物理內存。如果物理內存不足以支撐您日常使用全部的程序的話(體現在日常使用時內存滿了導致的卡頓,死機),使用swap也許會對您有些幫助。這樣可以避免 out of memory conditions,Linux內核OOM Killer機制將嘗試通過殺進程的方式來自動釋放內存。如果您想讓虛擬內存足夠使用,請添加相應的差值(或更多)作為交換空間。

啟用交換的最大缺點是性能較低,請參閱:#性能優化。因此,啟用swap是個人喜好問題:當物理內存用完時,有些人更喜歡殺死程序而不是啟用交換,而另一些人更喜歡啟用交換和較慢的系統。

注意: 連續的交換文件和交換分區之間沒有性能之別,兩者的處理方式是一樣的。

要檢查交換空間的狀態,使用

$ swapon --show

或者顯示物理內存以及交換使用情況:

$ free -h

交換分區[編輯 | 編輯原始碼]

交換分區可以用大多數 GNU/Linux 分區工具(例如 fdisk, cfdisk) 創建。交換分區在 MBR 中的類型為 82,在 GPT 中的類型為 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F

要將分區設置為Linux交換分區,請使用 mkswap(8) 命令。例如:

# mkswap /dev/sdxy
警告: 指定分區上的所有數據會丟失。

想要啟用一個設備作為交換分區:

# swapon /dev/sdxy

想要啟動時自動啟用交換分區,添加一個條目到 /etc/fstab:

UUID=device_UUID none swap defaults 0 0

UUID可以通過以下命令獲得:

lsblk -no UUID /dev/sdxy

其中 device_UUID 是交換分區的 UUID 。有關文件語法,請參見 fstab

提示:UUID 和 LABEL 應該比使用由內核給出的設備名稱更受青睞,因為設備順序可能在將來發生變化。詳細信息,請參見 fstab
注意: 如果交換分區位於使用 GPT 的設備上,fstab 配置項是可選的,請參考 #通過 Systemd 激活
警告: 在使用 madam 進行 RAID 設置時,如果開啟 swapon 命令的 discard 參數,將導致系統在啟動和運行時鎖定。

通過 Systemd 激活[編輯 | 編輯原始碼]

systemd 通過兩種機制來激活 swap 分區。兩種都是 /usr/lib/systemd/system-generators 內的可執行文件。generators 在啟動時運行並為 mounts 創建本地 systemd 單元。第一種機制是通過 systemd-fstab-generator 讀取 fstab 來生成單元,包括 swap 單元。 第二種機制是通過 systemd-gpt-auto-generator 檢查根磁盤來生成單位。這個機制僅在 GPT 磁盤上運行,並可以根據交換分區的GUID類型對其進行標識。詳細信息,請參閱 systemd#GPT partition automounting

關閉交換分區[編輯 | 編輯原始碼]

使用下面的命令關閉交換分區:

# swapoff /dev/sdxy

也可以使用 -a 參數來關閉所有的交換分區。

因為 swap 通過 systemd 管理,因此會在下一次系統啟動時再次激活。要永久禁用該特性,運行 systemctl --type swap 來查找 .swap 單元,然後 mask 它。

交換文件[編輯 | 編輯原始碼]

相比於使用一個磁盤分區作為交換空間,使用交換文件可以更方便地隨時調整大小或者移除。當磁盤空間有限(例如常規大小的SSD)時,使用交換文件更加理想。

注意: 自Linux內核版本5.0起,Btrfs支持交換文件,但有限制。有關更多信息,請參見 Btrfs#交換文件

建立交換文件[編輯 | 編輯原始碼]

注意: 如果您使用Btrfs,請按照 Btrfs#交換文件 初始化交換文件,不要使用下面的方式。

使用 dd 去創建一個由你自己指定大小的交換文件。例如,創建一個 512 MiB 的交換文件:

# dd if=/dev/zero of=/swapfile bs=1M count=512 status=progress
注意: 使用 dd to allocate a swap file is the most portable solution,有關更多信息,請參見 swapon(8) § Files with holes

為交換文件設置權限(交換文件全局可讀是一個巨大的本地漏洞):

# chmod 0600 /swapfile

創建正確大小的文件後,將其格式化用來作為交換文件:

# mkswap -U clear /swapfile

啟用交換文件:

# swapon /swapfile

最後,編輯 /etc/fstab,在為交換文件添加一個條目:

/etc/fstab
/swapfile none swap defaults 0 0

有關更多信息,請參見 fstab#Usage.

注意: 交換文件必須由文件系統上的位置指定,而不是由UUID或標籤指定。

刪除交換文件[編輯 | 編輯原始碼]

如果要刪除一個交換文件,必須先停用它。

作為root運行:

# swapoff /swapfile

然後即可刪除它:

# rm -f /swapfile

最後從 /etc/fstab 中刪除相關條目

在內存中的壓縮塊設備[編輯 | 編輯原始碼]

如果使用了交換文件或分區,默認會支持 zswap。如果使用 zram 內存壓縮塊設備,就不再需要交換文件或分區。zramzswap 的區別請參考 Improving performance#zram or zswap

交換加密[編輯 | 編輯原始碼]

查看 dm-crypt/交換分區加密英語dm-crypt/Swap encryption

性能優化[編輯 | 編輯原始碼]

交換操作通常比直接訪問RAM中的數據慢得多。完全禁用交換以提高性能有時會導致性能下降,因為它會減少VFS緩存的可用內存,從而導致更頻繁地使用寶貴的磁盤I/O。

可以調整交換值以提高性能:

交換值(Swappiness)[編輯 | 編輯原始碼]

swappiness sysctl 參數代表了內核對於交換空間的喜好(或厭惡)程度。Swappiness 的值可以是 0 到 200 之間 (在Linux內核版本低於5.8時最大值為100),默認值為60。設置這個參數為較低的值會減少內存的交換,從而提升一些系統上的響應度。較高值會導致內核嘗試使用交換空間,而值100意味着各IO的喜好(或厭惡)程度相等。眾所周知,在許多系統中,在足夠的內存上使用較低的值可以提高響應能力。

要查看當前交換值(Swappiness),請執行以下操作:

$ sysctl vm.swappiness

此外,可以讀取文件 /sys/fs/cgroup/memory/memory.swappiness(僅適用於 cgroup v1) 或 /proc/sys/vm/swappiness 以獲得原始整數值。

要臨時設置交換值(Swappiness),請執行以下操作:

# sysctl -w vm.swappiness=10

要永久設置交換值,請創建sysctl.d(5)配置文件。例如:

/etc/sysctl.d/99-swappiness.conf
vm.swappiness=10

To have the boot loader set swappiness when loading the kernel, add a kernel parameter, e.g. sysctl.vm.swappiness=10.

要測試和了解這可能起作用的原因,請查看此文章.

VFS 緩存壓力[編輯 | 編輯原始碼]

vm.vfs_cache_pressure 是另外一個影響交換性能的 sysctl 參數,這個參數控制內核回收 VFS 緩存的程度,增大數值會增加回收 VFS 緩存的頻率[1]. 更多信息請閱讀 Linux kernel documentation

優先級[編輯 | 編輯原始碼]

如果你有多個交換文件或交換分區,你應該考慮給它們各自分配一個優先級值(0 到 32767)。在使用較低優先級的交換區域之前,系統會優先使用較高優先級的交換區域。例如,如果你有一個較快的磁盤 (/dev/sda) 和一個較慢的磁盤 (/dev/sdb),給較快的設備分配一個更高的優先級。優先級可以在 fstab 中通過 pri 參數指定:

/dev/sda1 none swap defaults,pri=100 0 0
/dev/sdb2 none swap defaults,pri=10  0 0

或者通過 swapon 的 --priority 參數:

# swapon --priority 100 /dev/sda1

如果兩個或更多的區域有同樣的優先級,並且它們都是可用的最高優先級,頁面會按照循環的方式在它們之間分配。

分片[編輯 | 編輯原始碼]

不需要使用 RAID 提高交換的性能,只要在 /etc/fstab 中給交換設備設置相同的優先級,內核會將交換分片到多個設備。詳情請參考 Software-RAID 指南