Linux記憶體不足又不想買更多RAM,該怎麼辦呢,大家都會想到使用SWAP吧!
SWAP又稱置換空間、虛擬記憶體,這個技術非常古老,幾乎所有的Linux發行版都有使用。它將硬碟的一部份作為RAM,在RAM不夠的時候讓程式利用,免得記憶體不足(OOM)導致程式被系統中止。
Linux系統的SWAP可以是一個分區(swap partition),或者單一檔案(swapfile)。需要RAM就建立多大的SWAP,例如根據SWAP大小=2倍實體RAM
的大拇指定律,在擁有16GB實體RAM的電腦建立32GB的SWAP,就有額外的32GB RAM可以用。
但SWAP有個問題,因為在硬碟上跑,SWAP速度是比實體RAM要慢的,把程式丟在裡面跑會拖慢速度。將程式切換到SWAP可能短暫導致桌面卡頓。還有就是長期寫入大量資料會傷害SSD。
這個時候有兩個改進方案可以考慮,那就是「zSWAP」與「zRAM」,能夠增加SWAP的效能。他們都是Linux核心提供的功能,應當所有發行版都支援。
本文我們以搭載Linux 6.0以上核心版本的Ubuntu系統為例子。
1. 要選zSWAP還是zRAM?#
先說zRAM,技術上來說,zRAM會在實體RAM上面分配一個區域建立ramdisk,也就是/dev/zram
,透過壓縮分頁換取更多RAM,得到一塊速度更快的「SWAP」。zRAM還可以讓系統完全不必依賴SWAP檔案,又能擁有更多RAM。你只需要讓CPU額外付出一些心力去處理壓縮的部份。值得注意的是,zRAM可以搭配現有的SWAP檔案使用,將SWAP優先度降低,真的RAM不夠用了才寫入到SWAP,作為應急手段。
預設啟用zRAM的Linux發行版只有Fedora 41和Pop!_OS 24.04。
再來是zSWAP,它依賴現有的SWAP檔案,會將一部份RAM的分頁壓縮,在壓縮RAM後空間不足的情況下才會將分頁檔寫入到SWAP檔案。你只需要讓CPU額外付出一些心力去處理壓縮的部份。因此我們可以說,zSWAP是現有SWAP機制的一種改進,減少了舊有SWAP機制寫入資料過多的問題。
幾乎沒有Linux發行版啟用zSWAP,需要手動開啟。
順帶提一下,有些文章在討論zRAM和zSWAP的時候會一併講到zCache,不過這個技術開發停滯,很久以前就從Linux核心移除了。
這二個技術都是要拯救RAM太少的問題,開下去後帳面上可用的RAM會變大,例如16GB的實體RAM能額外擁有16GB RAM。但是同時啟用二個的意義不大,還可能會互相衝突。
為何我要選zSWAP而非zRAM呢?
講個實際例子,為了跑.gguf格式的AI生成影片模型Wan 2.1,我需要在16GB實體RAM的機器準備總計32GB的RAM,使用zRAM就得計算一下壓縮比。我以為zRAM能完全不依賴SWAP檔案,但我注意到zRAM就算設定成實體RAM兩倍大小還是容易出現OOM。看來zRAM再怎麼壓縮也抵不過暴力吃RAM的程式,有些資料不能壓縮,那麼zRAM設再大也沒有用,恐怕還是得做一個SWAP檔案備用。
這樣的話zSWAP會是比較好的選擇,它依賴現有的SWAP檔案,在壓縮RAM後空間依然不足的情況下才會將分頁檔寫入到SWAP檔案。
還有,既然要依賴SWAP檔案了,要嘛zRAM配SWAP,不然就zSWAP配SWAP。後者不用計算壓縮比多少,SWAP檔案直接新增下去就知道有多少額外RAM能用了。
雖然如此,我文章還是提供啟用zRAM的方式作為參考。
2. 壓縮演算法比較#
zRAM和zSWAP都會用到演算法來壓縮RAM,這裡簡單介紹。
目前Linux 6.0核心提供下面幾個壓縮演算法,效能有些微差異,請依照需求選擇。不然就維持預設值zstd
就好,這個兼顧速度與壓縮比,不會吃太多CPU資源。
名稱 | 壓縮比 | 速度 |
---|---|---|
lzo | 低 | 非常快 |
lz4 | 低 | 最快 |
zstd | 高 | 中等 |
lzma | 非常高 | 慢 |
zlib | 高 | 慢 |
deflate | 高 | 慢 |
3. 確認系統現有的SWAP#
如果是Ubuntu的話,預設在安裝的時候應該會自動建立一個swapfile,位於/swap.img
。並透過/etc/fstab
開機自動掛載。
利用free -h
指令或者htop
能夠確認系統目前的SWAP大小,如下範例輸出:
total used free shared buff/cache available
Mem: 15Gi 14Gi 429Mi 680Mi 1.8Gi 1.3Gi
置換: 15Gi 8.5Gi 7.5Gi
另外透過smemstat -mT
指令,可以知道有哪些程式執行於RAM,哪些程式在SWAP執行。
4. 建立SWAP檔案#
因為我要用zSWAP,必須要建立SWAP檔案。zRAM雖然不需要SWAP,但可以將其作為應急手段。
如果已經有SWAP檔案就跳過這段。
- 若要修改現有SWAP大小,可以用以下指令停用SWAP,並將其移除。
sudo swapoff -a
sudo rm /swap.img
- 然後,建立新的SWAP檔案。檔案大小就設定為實體RAM的兩倍,例如我有16GB實體RAM,就建立32GB的SWAP。
sudo fallocate -l 32G /swap.img
sudo chmod 0600 /swap.img
sudo mkswap /swap.img
sudo swapon /swap.img
- 編輯fstab
sudo vim /etc/fstab
- 確認SWAP檔案在開機後自動掛載。如果不這樣設定,則SWAP不能使用。
/swap.img none swap sw 0 0
5. 啟用zSWAP#
不要同時使用zSWAP和zRAM
Ubuntu透過傳遞核心參數啟用。必須先要有SWAP檔案才可以使用zSWAP。
- 編輯GRUB
sudo vim /etc/default/grub
- 加入以下內容。
zswap.enabled
啟用zSWAP,zswap.compressor
壓縮演算法選zstd。max_pool_percent
設定為60,偏好將分頁留在RAM,而非移動到SWAP。zswap.zpool
分配器使用zsmalloc。
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash zswap.enabled=1 zswap.compressor=zstd zswap.max_pool_percent=60 zswap.zpool=zsmalloc"
- 更新GRUB,重開機
sudo update-grub
sudo reboot
- 確認zSWAP是否有啟用。
sudo dmesg | grep zswap
6. 啟用zRAM#
不要同時使用zRAM和zSWAP
Ubuntu提供兩種新增zRAM的小工具,分別是「zramswap」和「systemd-zram-generator」,後者比較多發行版使用。
- 確認zSWAP沒有啟用,若有的話需要在GRUB加入
zswap.enabled=0
停用。
sudo dmesg | grep zswap
- 安裝systemd-zram-generator套件
sudo apt install systemd-zram-generator
- 編輯設定檔
sudo vim /etc/systemd/zram-generator.conf
- 填入以下內容,具體來說,如果想要在擁有16GB實體RAM的機器擁有16GB額外的VRAM,要讓zRAM壓縮比接近1:3,那麼zRAM的數值需要至少設定為實體RAM的1倍以上或者更高。另外將zRAM的優先度設定為最高,SWAP作為最後的應急手段。
[zram0]
zram-size = ram * 2
compression-algorithm = zstd
swap-priority = 100
fs-type = swap
- 啟用服務
sudo systemctl enable --now [email protected]
- 利用指令
zramctl
列出zRAM的使用情況。
NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd 31G 1.1G 227.8M 404.3M 4 [SWAP]