# 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のメモリが不足していると断定するには不十分です。

プロセス一覧はRSSをKiB単位で報告しますが、`free -h`は人間が読みやすい単位を使います。また、共有ページとVMのオーバーヘッドがあるため、プロセスの行を合計してもタスク マネージャーのVmmemWSLの数値と必ずしも一致するとは限りません。合計を無理に一致させようとせず、大きい行から所有者を特定し、そのうえで該当するワークロードを調べてください。

Dockerが関与している場合は、次の読み取り専用コマンドで実行中のコンテナを特定し、リソースサンプルを1回取得できます。[Docker stats reference](https://docs.docker.com/reference/cli/docker/container/stats/)も参照してください:

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

調査対象のDockerバックエンドに接続されている環境で実行してください。別のDockerコンテキストはリモートマシンを指していることがあるため、実行前にターゲットを確認してください。コンテナに表示されるメモリの数値とWSL VM全体の合計では、対象範囲が異なります。

3つの状態を比較してください。AIジョブが始まる前、実行中、そしてアプリケーションが通常どおりモデルをアンロードしたかジョブを停止した後です。大きいプロセスが生き残っている場合、そのプロセスを動かし続けるべきかどうかを決める代わりにキャッシュ回収を当てにするわけにはいきません。プロセスは縮小したのにキャッシュが残っている場合は、回収の挙動がより重要な問題になります。

## 現在の回収設定を確認する

Microsoftの[WSL構成リファレンス](https://learn.microsoft.com/en-us/windows/wsl/wsl-config)では、グローバルなWSL 2設定を`%USERPROFILE%\.wslconfig`に置いています。これはディストリビューション内の`/etc/wsl.conf`とは異なります。

現在のリファレンスでは、`autoMemoryReclaim`が`[experimental]`の下に記載されており、`dropCache`が既定値、`gradual`が別のサポートされるモードです。したがって、一般に無効になっている既定値を有効にするという古い助言は古くなっている可能性があります。何かを追加する前に、インストールされているWSLのバージョンと既存の構成を確認してください。

その設定をサポートするバージョンで、意図的にキャッシュの段階的な回収を行いたい場合は、次のエントリを既存のファイルにマージします：

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

無関係な設定を上書きしたり、重複するセクションを作成したりしないでください。これはキャッシュされたメモリの回収方法を変更するものであり、アクティブなモデルやデータベースの必要メモリを減らすものではありません。変更を維持するかどうかを決める前に、同じワークロードを比較してください。

## 既存の設定を編集し、戻る道を残す

エクスプローラーで`%USERPROFILE%`を開き、`.wslconfig`を作成または編集する前にファイル名拡張子を有効にしてください。誤って`.wslconfig.txt`として保存されたファイルは、意図した設定ではありません。まず既存の設定をバックアップにコピーし、メモリに関係しないセクションは保持してください。

既存の`[experimental]`セクションの1つで、テスト対象の回収エントリだけを変更してください。新しいファイルが必要になるのは、設定が存在せず、意図的な設定変更が正当化される場合だけです。異なる記事から例をコピーした後に、`dropCache`行と`gradual`行の両方を追加したり、セクションを重複させたりしないでください。

Microsoftが文書化しているデフォルトでは、すでにキャッシュが回収されます。これを`gradual`に変更するのはポリシー上の実験であり、常にメモリがより多く節約されるアップグレードではありません。即時回収よりも長くキャッシュが残る可能性があります。現在の挙動に問題が実証されていないなら、デフォルトのままにして、代わりにアクティブなワークロードを調べてください。

安全なWSL再起動を経て変更を適用した後、同じジョブを繰り返し、Windowsの応答性、Linuxの利用可能メモリ、ジョブが完了するかどうかを観察してください。変更が役に立たない場合は、バックアップから以前のエントリを復元し、同じ保存と再起動の注意事項に従ってその復元を適用してください。実験的な1行を削除するために設定全体を消去しないでください。

## WSLの作業を保存してから再起動する

構成の変更は、WSL環境の再起動時に適用されます。Microsoftの[基本コマンド](https://learn.microsoft.com/en-us/windows/wsl/basic-commands)には、グローバルなシャットダウンコマンドが記載されています：

```
wsl --shutdown
```

使用する前に、ファイルを保存し、トレーニングや推論のジョブを停止し、影響を受けるコンテナやデータベースを通常どおりシャットダウンしてください。このコマンドは、Docker Desktopの背後で動作しているものを含め、実行中のすべてのディストリビューションとWSL 2 VMを停止します。選択的にメモリを削減するボタンではありません。

シャットダウン後に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`は8GBの制限を意味し、ディストリビューションごとに8GBを予約するわけではありません。これは構文の例であり、すべてのPCに推奨される予算ではありません。複数のWSL 2ディストリビューションはグローバルなVM予算を共有するため、選ぶ際にはそれらの同時作業も含めてください。

作業を保存してWSLを再起動した後、ディストリビューション内で`free -h`が報告する合計を調べ、システムのオーバーヘッドを考慮しつつ意図した上限と比較してください。次に実際のモデルまたはビルドを実行します。タスク マネージャーの数値が小さくなっても、Linuxのジョブが強制終了されたりスワップに時間を使ったりしているなら成功ではありません。

上限が無視されているように見える場合は、ファイルを所有するWindowsアカウント、その拡張子、対象のディストリビューションがWSL 2かどうか、古いVMが完全に停止したかどうかを確認してください。これらの確認は、数値を何度も下げるよりも情報量が多くなります。同時に2つ目の実験としてスワップを無効にしないでください。それによりワークロードが予算に達したときの挙動が変わるためです。

Dockerのワークロードでは、Dockerの通常のシャットダウンとデータ永続化の挙動をそのまま保ってください。ターミナルを閉じてもコンテナが必ず停止するとは限らず、WSL全体のシャットダウンは無関係な複数のサービスを中断させることがあります。VM全体の変更を適用する前に、データベースやトレーニングの作業をそれぞれのアプリケーションの制御で保存してください。

## RAMと仮想ディスクの容量は別々に扱う

| 問題 | 関連する調査 |
| --- | --- |
| AIタスクの実行中にメモリが増加する | モデル、コンテキスト、同時に動作するLinuxの作業 |
| 作業終了後もキャッシュが残る | 回収の動作とWSLのバージョン |
| PC全体がメモリ不足になっている | Windowsのメモリとコミット |
| WSLのディスクファイルが大きいまま | RAMではなくファイルと仮想ディスクのストレージ |

[Windowsのメモリガイド](/ja/windows/blog/windows-high-memory-usage)では、ホスト側の数値について説明しています。ディスク容量については、別の[DockerとWSLのストレージガイド](/ja/windows/blog/docker-wsl-disk-space-windows)を参照してください。`wsl --unregister`をクリーンアップの近道として決して使用しないでください。高メモリの数値を解決するのではなく、ディストリビューションとそのデータを削除します。


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