Windows WSL2 Memory Auto Release

Allen Kuo (kwyshell)
6 min readApr 16, 2024

--

Windows 自從引入 Linux 子系統後,真的對開發者來說是個大福音。尤其在WSL2 (Windows Subsystem for Linux 2) 對於Linux的支持更全面也更完整。可以無縫的在 Windows 與 Linux 存取,再配合諸如Visual Studio Code的WSL2整合,形成了一個極度友善又實用的開發環境。

但是有時候事情總不都是那麼順利。WSL2目前使用上最大的問題就是WSL2會瘋狂消耗Windows 主機的Memory。而且這個消耗似乎沒有底線,你可以眼睜睜的看WSL2瘋狂的消耗主系統的Memory直到系統發出無RAM可用的窘境。然後接下來只能重新開機一途。

延伸閱讀: Out of Memory, 電腦RAM老是莫名的不夠用?

WSL2 與 主機的共享 Memory 設計

WSL2 Arhcitecture

首先我們看看看這張來自Docker討論區的WSL2 Architecture。由於Linux Kernel的引入,Windows核心具備了運行Linux的能力。然後這個WSL子系統與Windows主機共享著各種資源。甚至透過DrvFS/P9 來共享NTFS的內容。各種Linux 服務、程式 等等都能在同一台主機上同時運行。

一切雖然美好,但是同時系統也付出很大的代價,那就是同時要提供資源給兩個系統,同時要管理兩側的資源。Memory管理就是其中一個超大罩門。常見的情況是甚麼都沒運行,WSL就已經消耗掉將近1GB的RAM。如果運行更多的process後,雙系統更是消耗了為數可觀的資源。更甚者,WSL甚至沒有察覺自己已經耗盡HOST共享Memory而不自知。最後可能就主機無RAM可用,無法支持WSL2。WSL2也因為主機無力運行而導致各種服務崩潰。

官方的解決方案:

看來微軟自己也知道這個問題。官方建議的方案就是給WSL2設定一個上限。與有一些實驗性的功能來解決問題。

修改wsl.config (%userprofile%\.wslconfig)

  • memory
    Limits VM memory to use no more than 4 GB, this can be set as whole numbers using GB or MB (限制VM使用的RAM的最高上限)
    memory=4GB
  • autoMemoryReclaim
    autoMemoryReclaim string disabled Automatically releases cached memory after detecting idle CPU usage. Set to gradual for slow release, and dropcache for instant release of cached memory. (實驗性功能,自動釋放Cache 在偵測到CPU IDLE USAGE的情況下)

其他內容請參閱
https://learn.microsoft.com/en-us/windows/wsl/wsl-config

這幾個改善,老實說自己都不是很滿意。首先限制上限基本上就是給個最高配額。但是對於希望雙方都能共享完整Memory使用情況就不是那麼好用。另一個 “autoMemoryReclaim” 這是個重要的改善方針,看來微軟自己也很明白Cache是個大問題,但是這個方案使用起來似乎也沒那麼有效。甚至有些時候沒能真正得起到作用。

我的解決方案:

跟我的OOM文章一樣,我也是寫了個工具來克服這個問題。

首先,由於雙方是共享Memory所以我可以藉由推算 Linux “free” 的 Memory 剩餘容量來估算是不是要發動 “取回Memory” 這個操作。再者,我們可以觀察 /proc/meninfo 中,MemAvailable 這個選項的大小作為判讀發動時機。我這個script將採用這個雙指標來衡量我系統是不是處於迫切需要取回可用Memory得時刻。

如同script所寫那樣,當 MemAvailable < 10% 或是 Free < 10%,我們就會啟動取回Memory的動作,隨後等待1分鐘做下一次檢查,如此往復。

取回Memory,到底是取回甚麼Memory呢?

如同微軟官方的 “autoMemoryReclaim” 與 我對WSL啟用 swap on/off 與 drop caches 那樣,這些指令都在強迫WSL釋放可能的File Cache。由於檔案系統為了加快IO的處理效率,會不斷的Cache檔案系統,以達到減少直接存取緩慢的DISK上的檔案。但是WSL2的這個機制對Host端的Windows來看到像是個吃Memory的怪獸。

其實OS本來都會對檔案進行Cache的動作。Windows也回拿剩餘的Memory來做為IO Cache。但是這些借出去的都稱為待命中的Memory,隨時系統需要更多的Memory時,都能釋放出來轉為可用的資源。然後WSL與Windows兩個OS各自Cache各自的檔案與資源,看起來卻不像相互合作,而是互相耗盡對方的資源。如果放任不管,最終就是雙雙耗死對方,最後同歸於盡。比如你下載個AOSP源碼,然後Windows Side開個Visual Studio Code 開啟這個目錄。Visual Studio Code 的資源搜索器會不斷的掃描AOSP巨量的檔案。 放個幾個小時,你就會觀察到整個 VMmemWSL 消耗了非常可觀的系統資源(這結果真讓人啼笑皆非~~)

驗證與測試可用性!

首先你必須在WSL中,以su的身分運行這段bash script。運行結果如下,

可以清楚看到,在我的一台主機上,系統會在WSL free memory 剩餘10%以下觸發。隨後系統又回逐步回到70%的資源。我們可以清楚的看到這個Cache機制是多無腦的耗盡系統資源。整個跨度竟然來到了接近60%的系統資源。

如果你也有這方面的煩惱,希望我這個小script能幫你解決WSL2這個煩人又無腦的問題。

參考連結:

--

--

No responses yet