為什麼 zram 與其“壓縮”值相比佔用更多的記憶體?
我設置了 zram 並在我的 Linux 機器中進行了廣泛的測試,以衡量它在我的場景中是否真的有幫助。但是,我很困惑 zram似乎耗盡了整個未壓縮數據大小的記憶體。當我輸入“zramctl”時,我看到了這個:
NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT /dev/zram0 2G 853,6M 355,1M 367,1M 4 [SWAP]
根據 zramctl 的幫助命令,
DATA
是未壓縮的大小和TOTAL
包含元數據的壓縮記憶體。然而,當我輸入 時swapon -s
,我看到了這個輸出:Filename Type size used Priority /dev/sda2 partition 1463292 0 4 /dev/zram0 partition 2024224 906240 5
906240
是以千字節為單位的已用記憶體,轉換為 zramctl 的 853,6MDATA
值。這給人的印像是壓縮的 zram 設備需要的記憶體多於節省的記憶體。一旦DATA
滿了,它實際上就開始交換到磁碟驅動器,所以它確實是滿的。為什麼 zram 貌似佔用了原始數據大小的記憶體?為什麼不是
COMPR
or的大小TOTAL
?在網際網路上似乎還沒有這方面的資料,因為我還沒有找到任何關於這方面的資訊。謝謝!
所以經過更多的測試和觀察,我有了一些非常有趣的發現。
DATA
確實是佔用交換空間的未壓縮記憶體量。但乍一看,它非常具有欺騙性和混淆性。當您設置 zram 並將其用作交換時,disksize
並不代表 zram 將用於壓縮數據的記憶體總量。相反,它代表zram 將壓縮的未壓縮數據的總量。所以你可以創建一個大小為 2 GB 的 zram 設備,但實際上 zram 將在總壓縮記憶體約為 500 - 1000 MB 後停止(當然取決於你的場景)。swapon -s
或 Gnome 的系統監視器之類的命令會顯示 zram 設備的未壓縮數據大小,就像DATA
的 zramctl。值得慶幸的是,實際上,zram 實際上並沒有用完報告的記憶體量。但這意味著在實踐中,您實際上必須創建一個等於您擁有的 RAM + 50% 的 zram 磁碟大小才能真正利用它,而不是創建一個等於 RAM 大小一半的磁碟大小,就像 zram-config 錯誤地做的那樣. 但請繼續閱讀以了解更多資訊。這是更深層次的背景:為什麼我這麼肯定?因為我也用 zswap 測試了這個。我已經編譯了一個自己的核心,與 anon_prio 相比,我降低了 mm/vmscan.c 中的 file_prio 值(在較新的 Linux 5.6 核心中,變數已分別重命名為 fp 和 ap)。減小的 file_prio 值將使核心不再丟棄有價值的記憶體記憶體。預設情況下,即使
vm.swappiness
是 100,核心也會丟棄大量記憶體的 RAM 數據,包括備用記憶體和活動程序。當您真正想要使用 zram 時,預設配置的性能損失在記憶體壓力情況下是極端的,因為您絕對****希望核心交換很少使用的並且高度可壓縮的記憶體方式更頻繁。有了更多可用記憶體,您就有更多空間用於記憶體數據。這樣記憶體的數據就不會以高得離譜的速度被丟棄,Linux 也不必反復重新讀取某些已清除的程序文件記憶體。在經典硬碟驅動器上進行測試時,您可以輕鬆驗證性能影響。回到我的 zswap 測試:使用我的自定義核心,一旦我達到 50 - 70% 的記憶體標記,zswap 就有足夠的記憶體來壓縮。Gnome 的系統監視器立即顯示頁面分區的交換數據使用率很高,但奇怪的是,根本沒有硬碟分頁!這當然是 zswap 的設計,它自己交換最近最少使用的記憶體。但有趣的是,系統無論如何都會報告交換分區的如此高的交換使用率,因此最終您會受到交換分區或交換文件大小的限制。即使所有記憶體都被壓縮,你也必須至少具有未壓縮數據的交換大小。因此,即使實際上 zswap 中 4 GB 的交換記憶體只使用了 1 - 2 GB,您的交換也需要具有未壓縮數據大小的大小。zram 也是如此,但這裡的記憶體至少實際上並沒有被保留。好吧,當然,除非您將 zswap 與動態增長的交換文件一起使用。
至於 zram,還有一個非常有趣的細節可以支持我所做的觀察:
創建大於兩倍記憶體大小的zram 沒有什麼意義, 因為我們期望壓縮比為 2:1。請注意,zram 在不使用時使用大約 0.1% 的磁碟大小,因此巨大的 zram 是浪費的。
這意味著要有效地使用 zram,您至少必須創建一個與您安裝的 RAM 相等的磁碟大小。由於壓縮率高,我建議使用 GB 的 RAM + 50%,但上面的引述暗示如果超過 +100% 則沒有多大意義。此外,由於我們必須指定與未壓縮數據大小相匹配的磁碟大小,因此控制和預測實際的實際記憶體使用量要困難得多。從上面有用的官方資源中,我們可以使用
TOTAL
以下命令限制實際記憶體使用量(等於 zramctl 的值):echo 1G > /sys/block/zram0/mem_limit
. 但實際上,這樣做會鎖定機器。因為系統嘗試仍然交換到它,但是 zram 施加了限制,並且機器鎖定了超高 CPU 使用率。這種行為根本不是故意的,這加強了我的印象,即整個故事的某些內容非常不穩定。總結一下:
- 您在 zram 設備創建期間設置的
disksize
基本上是虛擬磁碟大小,這並不代表真實的 RAM 使用情況。- 您必須預測場景的實際 RAM 使用情況(壓縮比),或者確保您永遠不會創建太大的 zram 磁碟大小。您目前的 RAM 大小 + 50% 在實踐中應該幾乎總是可以的。
- 不幸的是,Linux 核心的預設配置完全不適合 zram 壓縮,即使設置
vm.swappiness
為 100。您需要製作自己的自定義核心才能真正使用這個方便的功能,因為 Linux 清除了太多的文件記憶體而不是釋放通過更早地交換最可壓縮的數據來增加記憶體。具有諷刺意味的是,解決這種情況的有用更新檔從未被接受。- 一旦壓縮數據達到該門檻值,使用 zram 限制
echo 1G > /sys/block/zram0/mem_limit
將鎖定您的系統。您最好使用預測良好的 zram 磁碟大小來限制 zram 的使用,因為似乎沒有其他替代方法可以限制。