Ubuntu 複製大檔案讓系統變慢的解法和原因

複製大檔案後, 系統會變得超慢, 明明 htop 顯示沒有執行 application, 卻會顯示全部 CPU (我用的機器是四核心) 都被 kernel 占住 (htop 用紅色表示)。而且 ram 明明沒滿, 卻用掉大量的 swap。查了一下後發現這已是很舊的「bug」, 仍未被解掉, 參見 Ubuntu bug 226784 365775

《Linux: how to explicitly unswap everything possible?》 提到關掉 swap 可以讓 kernel 釋放 swap, 好讓 application 回頭用 ram。所以先打 "swapoff -a", 用 htop 會看到 swap 上限先縮為目前的使用量, 而非系統的設定值。接著以極緩慢的速度縮小, 最後到零。這時就能再打 "swapon -a" 重開 swap。這時仍會看到 kernel 占掉全部 CPU, 不過等個一陣子 (大概十分鐘吧) , 系統就恢復正常了。

為了避免再度發生這問題, 查了一下相關資料, 才發現這不太算是 bug。原因出在 linux kernel 決定是否要將 ram 裡的資料搬到 swap 的策略。詳細的說明見《Patrick Lauer: The mistery of swappiness》《swapping behavior》 (後面那篇挺好笑的, 推薦一看!), 大意是當 application 和 kernel cache 用的記憶體量過高時, 即使 ram 仍有空間, kernel 會參考 swappiness 的值, 決定要捨棄 cache 還是將 application 的記憶體搬到 swap。swappiness 的值介於 0 ~ 100 之間, 值愈高, kernel 愈會將 application 用的記憶體搬到 swap。悲慘的是, 預設值一直都是 60, 但現在的電腦有很大的 ram (早期 512MB vs. 現在最少 4GB), 用 60 的結果是, 明明還有很多空間可用, 一搬大檔案, file cache 吃掉過多記憶體, kernel 就將 application 用的記憶體搬到 swap, 於是整個系統進入莫明奇妙緩慢的狀態。

若要避免這問題再度發生, 參照這篇的說明修改即可:
  • sysctl vm.swappiness  # 顯示目前的 swappiness 的值
  • sudo sysctl vm.swappiness=5  # 將目前的設定改為 5
  • sudo vi /etc/sysctl.conf: 加入這行 "vm.swappiness=5"  # 開機後自動設為 5
實測後, 改了 swappiness 後就沒有發生 swap 暴增, 然後 kernel 占掉全部 CPU 的情況了, 可喜可賀!! 有文章提到不建議設為 0, 稍微留些 cache 方便檔案操作。另外, 就算設為 0, kernel 只是盡量不將 application 用的記憶體搬到 swap, 待 ram 真的完全被用光時, kernel 還是得強迫擠出空間給 cache 用, 到時系統也會變慢。

留言

這個網誌中的熱門文章

(C/C++ ) 如何在 Linux 上使用自行編譯的第三方函式庫

熟悉系統工具好處多多

virtualbox 使用 USB 裝置