# VmmemWSL 記憶體偏高：先找出工作負載，再回收 RAM

工作管理員中的 `VmmemWSL` 代表 WSL 虛擬機器環境所使用的資源。其記憶體可能包含使用中的 Linux 工作負載與快取。如果有 Docker、AI 模型伺服器或開發工具在其中執行，結束 Windows 編輯器不一定會停止該工作。

首先判斷記憶體是屬於執行中的工作，還是工作結束後仍保留的快取。刪除 WSL 虛擬磁碟不是記憶體問題的解決方法，且可能破壞 Linux 環境及其資料。

## 在 WSL 內找出工作

從 PowerShell 檢查已安裝的環境：

```
wsl --version
wsl --list --verbose
wsl --list --running
```

在對應的 Linux 發行版內，使用這些唯讀檢視：

```
free -h
ps -eo pid,comm,rss --sort=-rss
```

Linux 的讀數與工作管理員的 VM 總量範圍不完全相同。用它們來定位程序並區分可用記憶體與檔案快取，不要強求每個數字都對得上。對於 Docker 所擁有的工作，檢查 Docker Desktop 執行中的容器，並透過其正常控制項停止預定的工作。

AI 伺服器可能在回應後仍將模型保持載入。如果不再需要該工作負載，請刻意停止它。不要只因為程序名稱不熟悉就隨意終止。

## 閱讀 Linux 記憶體取樣時，別把所有快取都當成洩漏

在 `free -h` 的輸出中，請留意 `available`，以及 `used` 和 `buff/cache`。Linux 會把閒置的記憶體用於檔案資料，其中一部分在應用程式需要時可以回收。因此，單看 `free` 數值偏小，並不足以證明 Linux 已經記憶體不足。

程序清單以 KiB 回報 RSS，而 `free -h` 採用較易讀的單位。此外，由於有共享分頁和 VM 額外開銷，把各程序列加總起來，未必等於工作管理員的 VmmemWSL 數值。請用數值最大的幾列找出擁有者，再檢查具名的工作負載，不要硬把總數湊成一致。

如果涉及 Docker，下列唯讀命令可列出執行中的容器並取得一次資源取樣，做法參考 [Docker stats 參考文件](https://docs.docker.com/reference/cli/docker/container/stats/)：

```powershell
docker ps
docker stats --no-stream
```

請在連線到要調查的 Docker 後端的環境中執行這些命令。不同的 Docker 環境定義可能指向遠端機器，因此動作前先確認目標。容器顯示的記憶體數值與整個 WSL VM 的總量，兩者的範圍不同。

請比較三種狀態：AI 工作開始前、執行期間，以及應用程式正常卸載模型或停止工作之後。如果大型程序仍然存活，那麼決定該程序是否該繼續執行，並不能靠快取回收來取代。如果程序縮小了但快取仍在，回收行為就成為更值得探討的問題。

## 檢查目前的回收設定

Microsoft 的 [WSL 設定參考](https://learn.microsoft.com/en-us/windows/wsl/wsl-config) 將全域 WSL 2 設定放在 `%USERPROFILE%\.wslconfig`。這與發行版內的 `/etc/wsl.conf` 不同。

目前的參考文件在 `[experimental]` 下列出 `autoMemoryReclaim`，預設值為 `dropCache`，另有支援的模式 `gradual`。因此，舊有建議啟用普遍停用的預設值可能已經過時。在新增任何內容之前，請檢查已安裝的 WSL 版本與現有設定。

如果刻意要在支援該設定的版本上啟用漸進式快取回收，請將此項目合併到現有檔案：

```
[experimental]
autoMemoryReclaim=gradual
```

不要覆寫無關的設定或建立重複的區段。這會改變快取記憶體的回收方式；它不會讓使用中的模型或資料庫需要更少記憶體。在決定是否保留變更之前，請比較相同的工作負載。

## 編輯現有設定，並保留還原的途徑

在檔案總管中開啟 `%USERPROFILE%`，並在建立或編輯 `.wslconfig` 之前啟用副檔名顯示。檔案若不小心存成 `.wslconfig.txt`，就不是預期的設定檔。請先將現有設定複製一份備份，並保留與記憶體無關的區段。

在現有的一個 `[experimental]` 區段下，只變更正在測試的那一項回收設定。只有在完全沒有設定檔，且確實有必要刻意變更設定時，才需要建立新檔案。不要同時加入 `dropCache` 和 `gradual` 兩行，也不要從不同文章複製範例後把同一區段重複一次。

微軟文件記載的預設值已經會回收快取。把它改成 `gradual` 是一種策略實驗，並不是一定更省記憶體的升級。它可能讓快取停留比立即回收更久。如果目前行為並沒有已證實的問題，就保留預設值，改為調查正在執行的工作負載。

透過安全地重新啟動 WSL 套用變更後，請重複執行同一個工作，並觀察 Windows 的回應速度、Linux 可用記憶體，以及工作是否能完成。如果變更沒有幫助，就從備份還原先前的項目，並以相同的先存檔再重新啟動的謹慎做法套用還原。不要為了移除一行實驗設定而把整個設定檔清空。

## 儲存工作後才重新啟動 WSL

設定變更會在 WSL 環境重新啟動時生效。Microsoft 的 [基本命令](https://learn.microsoft.com/en-us/windows/wsl/basic-commands) 記載了全域關機命令：

```
wsl --shutdown
```

使用前，請儲存檔案、停止訓練或推論工作，並正常關閉受影響的容器或資料庫。此命令會停止所有執行中的發行版與 WSL 2 VM，包括 Docker Desktop 背後的工作。它不是選擇性修剪記憶體的按鈕。

如果關機後 VmmemWSL 記憶體消失，即確認是已停止的環境所擁有。這無法區分記憶體洩漏、使用中的工作或有用快取。重新啟動所需服務，並在相同工作完成後進行比較。

## 將記憶體上限視為預算，而非修復

`.wslconfig` 的 `memory` 設定會限制 WSL 2 的可用記憶體。上限太低可能導致 Linux 應用程式失敗或大量使用交換。它不會移除程式需求。請在衡量工作負載與 Windows 也需要的 RAM 後再選擇，然後確認應用程式能成功完成。

Docker Desktop 的 [WSL 指引](https://docs.docker.com/desktop/features/wsl/) 討論其 WSL 後端的記憶體回收。請將設定保留在該後端，不要套用無關的 Hyper-V 指示。

## 確認記憶體上限確實生效

如果需要設定上限，請在現有設定的 `[wsl2]` 下加入 `memory`。例如 `memory=8GB` 代表 8 GB 的上限，而不是每個發行版各保留 8 GB。那只是語法範例，不是每台電腦都適用的建議額度。多個 WSL 2 發行版共用全域 VM 額度，因此選擇數值時要把它們同時執行的工作一併納入考量。

儲存工作並重新啟動 WSL 後，請在發行版內檢查 `free -h` 回報的總量，容許系統額外開銷後，再與預期上限比較。接著執行實際的模型或建置。如果 Linux 工作現在被終止，或時間都花在置換上，那麼工作管理員數字變小並不算成功。

如果上限似乎被忽略，請檢查擁有該檔案的 Windows 帳戶、副檔名、目標發行版是否為 WSL 2，以及舊的 VM 是否已完全停止。這些檢查比反覆調降數值更有幫助。不要同時把置換關掉當成第二項實驗，因為那會改變工作負載達到額度時的行為。

對於 Docker 工作負載，請維持 Docker 正常的關機與資料保存行為。關閉終端機未必會停止其中的容器，而全域關閉 WSL 可能中斷多個不相關的服務。在套用整台 VM 的變更之前，請先透過資料庫和訓練工作各自的應用程式控制項保存進度。

## 將 RAM 與虛擬磁碟空間分開處理

| 問題 | 相關調查 |
| --- | --- |
| AI 工作執行時記憶體上升 | 模型、上下文與並行 Linux 工作 |
| 工作結束後快取仍保留 | 回收行為與 WSL 版本 |
| 整台電腦承受壓力 | Windows 記憶體與認可 |
| WSL 磁碟檔案維持很大 | 檔案與虛擬磁碟儲存，而非 RAM |

[Windows 記憶體指南](/tw/windows/blog/windows-high-memory-usage) 涵蓋主機端讀數。關於磁碟容量，請使用另篇 [Docker 與 WSL 儲存指南](/tw/windows/blog/docker-wsl-disk-space-windows)。絕不要將 `wsl --unregister` 當作清理捷徑：它會移除發行版及其資料，而非解決記憶體讀數偏高的問題。


Canonical: https://mole.fit/tw/windows/blog/vmmemwsl-high-memory
