Memory

為什麼Linux在使用大量記憶體時變得無響應(無法觸發OOM)

  • September 4, 2021

我在 AWS 中使用 CentOS 7.5 實例,它有 16 個 CPU 和 32GB 記憶體。我發現當我執行以下命令時,整個系統將無響應,我無法再對其執行任何命令,甚至無法建立新的 SSH 會話(但仍然可以 ping 它)。而且我根本沒有看到OOM殺手被觸發,似乎整個系統永遠掛起。

stress --vm 1 --vm-bytes 29800M --vm-hang 0 

但是,如果我執行stress --vm 1 --vm-bytes 29850M --vm-hang 0消耗更多記憶體(50MB),OOM kill 將被成功觸發(我可以在 中看到它dmesg)。如果我執行stress命令以消耗少於 29800MB 的記憶體(例如stress --vm 1 --vm-bytes 29700M --vm-hang 0),系統將響應(並且沒有 OOM 終止)並且我可以像往常一樣執行任何命令。

所以它似乎29800MB是這個實例的“神奇數字”,如果我執行stress命令使用比它更多的記憶體,該命令將被 OOM 殺死,如果我執行stress命令使用比它更少的記憶體,一切都很好,如果我執行stress命令只使用 29800MB 記憶體,整個系統將無響應。而且我還在不同規格的 Linux 主機中觀察到相同的行為,例如在具有 72 個 CPU 和 144GB 記憶體的 CentOS 7.5 實例中,“幻數”是“137600MB”。

我的問題是,為什麼在使用記憶體的“幻數”時不會觸發OOM kill?

哦,這個話題已經討論過了。

看:

Linux 核心無法優雅地處理低記憶體壓力

讓我們談談房間裡的大象——Linux 核心無法優雅地處理低記憶體壓力

解決方案?各種守護程序,如earlyoom(在 Fedora 32 中預設安裝並啟用),這是我的最愛。還有其他的:

問題的根本原因是只有在嘗試執行所有程序時無法取得進展時才會啟動 OOM 殺手。請注意,“向前進展”被認為是一些記憶體可以持續可用,其中“持續”是在掃描整個虛擬記憶體頁表結構一次後至少 4 KB 的更多 RAM。

最壞的情況需要持續掃描該結構很長時間,以至於系統似乎掛起,因為此進度沒有時間限制,並且只要記憶體子系統可以向前推進,它就會嘗試繼續前進,儘管速度很慢。掃描整個記憶體最多可能需要 0.5 秒,最壞情況下的前進進度會導致 4 KB 可用記憶體。如果系統實際上需要例如 20 MB 來重新渲染顯示,則需要大約 2500 次記憶體掃描才能成功,這將需要半個多小時。顯然,一個螢幕刷新需要半小時的系統對於使用者來說相當於完全掛起系統,即使核心對進度感到滿意。

我認為最好的選擇是允許為記憶體子系統指定最大延遲,當延遲太高時,OOM 殺手會自動啟動(例如,記憶體管理子系統必須能夠提供每秒至少 100 MB 的可用空間,或者係統狀態應該被視為記憶體不足)。使用earlyoom或其他類似解決方案的問題是,為了避免負載高峰值的最壞情況行為,這些解決方案需要非常廣泛的安全裕度,這會使您浪費 RAM 來獲得安全裕度。

引用自:https://unix.stackexchange.com/questions/591566