WSL2がメモリを食い尽くして接続不能になった話と根本解決
発生した問題
CursorエディタからWSL2(Ubuntu 22.04)に接続しようとしたところ、以下のエラーで接続不能になった。
Error installing Cursor server [wsl exec: installServerScript]
Command failed with exit code 4294967295:
接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。
エラー コード: Wsl/Service/0x8007274c
タスクマネージャーを確認すると、VmmemWSL(WSL2の仮想マシンプロセス)がCPU 59%、メモリ15.5GBを占有し、システム全体のメモリ使用率が94%に達していた。
環境
- Windows 11 Home 25H2(ビルド 26200.8037)
- 物理メモリ: 32GB
- WSL2 + Ubuntu 22.04
- エディタ: Cursor(WSL Remote接続)
原因
1. WSL2のメモリ未解放問題(主因)
WSL2はHyper-V上の軽量VMとして動作する。Linux側のページキャッシュがメモリを確保し続け、Windows側に返却しないという既知の問題がある。
デフォルトではWSL2のメモリ上限は「物理メモリの50%または8GBの小さい方」だが、この制限が正しく機能しない場合や、上限近くまで使い切った状態が長時間続くことで、VM内部のネットワークスタック処理が遅延する。
2. ネットワークタイムアウト(表面的な症状)
エラーコード 0x8007274c はWindowsソケットの WSAETIMEDOUT。WSL2のVMがリソース逼迫により応答できなくなり、CursorのRemote Server接続がタイムアウトした。
つまり「接続が切れた」のではなく、「VM側が重すぎて応答を返せなかった」が正確な表現。
解決策
応急処置: WSL2の再起動
wsl --shutdown
これはWSL2のVMを一時停止するだけで、データやファイルは消えない。次にWSLを使う操作(ターミナル起動、Cursor接続等)で自動的に再起動される。
根本解決: .wslconfigの設定
C:\Users\<ユーザー名>\.wslconfig を作成(または編集)し、以下を記述する。
[wsl2]
memory=20GB
swap=2GB
networkingMode=mirrored
dnsTunneling=true
autoProxy=true
[experimental]
autoMemoryReclaim=gradual
設定後、wsl --shutdown でWSL2を再起動して反映。
各設定の解説と設定根拠
memory=20GB
効果: WSL2のメモリ上限を明示的に制限する。
設定根拠: 物理メモリ32GBの約63%を割り当て、Windows側に12GB残す構成。WSL側で開発をメインに行う場合、ビルド・LSP・linter等でメモリを消費するため多めに確保した。Windows側の12GBは、カーネル+Hyper-V(3〜4GB)とChrome等のアプリ(4〜5GB)で十分に余裕がある。
判断指針: メモリはCPUと異なり「使っていないから自動で譲る」という挙動をWSL2はしない(これが今回の問題の根本原因)。したがって上限の明示が必須。具体的な値はワークロードによるが、以下を目安にする:
| 用途 | 推奨値(32GB PCの場合) | Windows側残量 |
|---|---|---|
| WSLで開発メイン | 16〜20GB | 12〜16GB |
| WSL + Docker多用 | 20〜24GB | 8〜12GB |
| たまにWSL使う程度 | 8GB | 24GB |
Windows側は最低3〜4GB必要(カーネル、Hyper-V、ドライバ)。Chromeを開く場合はさらに4〜5GB。
注意: この値は経験則ベースの初期値であり、実際のワークロードに基づいて調整すべき。負荷時に free -h やタスクマネージャーを監視し、WSL側でメモリ不足が頻発するなら増やす、Windows側が逼迫するなら減らす。
processors(設定しない)
効果: 設定しない場合、WSL2は全CPUコアを利用可能。
設定根拠: CPUはメモリと性質が異なり、WSL2が使っていない時間帯は自動的にWindows側に譲られる。メモリのように「確保したら返さない」問題が存在しないため、明示的な制限は不要。特にi9-13900HX(24コア/32スレッド)のようなハイスレッド環境では、制限をかけるとビルド速度が不必要に低下する。
判断指針: CPUを制限すべきケースは「WSL側のプロセスがCPUを100%使い続けて、Windows側の操作が重くなる」場合のみ。通常の開発作業では発生しない。問題が起きてから制限する、で十分。
swap=2GB
効果: WSL2内のスワップ領域を設定する。メモリが不足した際にディスクを仮想メモリとして使う。
設定根拠: swapのデフォルト値はWSL2に割り当てたメモリの25%(memory=20GBなら5GB)。memory=20GBで通常の開発では十分なため、スワップは一時的なスパイク対策として控えめの2GBに設定した。スワップはSSDへの読み書きが発生するため、大きすぎるとSSDの寿命に影響し、スワップ発生時のパフォーマンスも低い。
判断指針: memory値を十分に確保している場合、swapは2〜4GBで十分。頻繁にスワップが発生する(free -h でSwap usedが常に高い)なら、swapを増やすのではなくmemoryを増やすのが正しい対処。
networkingMode=mirrored
効果: WSL2のネットワークモードをNAT(デフォルト)からミラーに変更する。
設定根拠: 今回の問題の直接的な対策。デフォルトのNATモードではWSL2のVMに独自のIPアドレスが割り当てられ、Hyper-Vの仮想スイッチを経由して通信する。スリープ復帰時にこの仮想スイッチが不安定になり、接続断が発生する。mirroredモードではWindowsのネットワークスタックをWSL2が直接共有するため、この問題が解消される。Microsoft公式ドキュメントで推奨されている設定。
判断指針: Windows 11 22H2以降であれば基本的にmirroredを推奨。ただしmirroredモードではWSL2側が独自IPを持たなくなるため、WSL内でサーバーを立ててWindows側からIPでアクセスするような構成では挙動が変わる場合がある。
dnsTunneling=true / autoProxy=true
効果: DNS解決をトンネリング経由にし、Windows側のプロキシ設定を自動適用する。
設定根拠: VPN環境やプロキシ環境でWSL2からの名前解決・外部通信が安定する。元の .wslconfig に設定されていたものをそのまま維持した。VPNやプロキシを使わない環境でも害はないため、残しておいて問題ない。
判断指針: VPN接続時にWSL内で git push や npm install が失敗する場合は、これらの設定が特に有効。
autoMemoryReclaim=gradual
効果: WSL2が未使用のページキャッシュを自動的にWindowsに返却する。
設定根拠: 今回の問題の核心への対策。WSL2のLinuxカーネルはファイルI/Oの結果をページキャッシュとして保持するが、このキャッシュをWindows側に返却しない既知の問題がある。gradual を設定することで、バックグラウンドで徐々にキャッシュを回収し、メモリの暴食を防ぐ。
判断指針: 値は2種類ある:
-
gradual(推奨): バックグラウンドで徐々にメモリを回収。パフォーマンスへの影響が小さい -
dropcache: 即座にページキャッシュを解放。I/O性能に影響が出る場合がある
通常は gradual で十分。gradual でもメモリ使用量が高止まりする場合に dropcache を検討する。
autoMemoryReclaimの注意点
autoMemoryReclaim は [wsl2] セクションではなく [experimental] セクションに記述する必要がある。[wsl2] に書くと以下のエラーが出る:
wsl: wsl2.autoMemoryReclaim の不明なキー
手動でのメモリ回収(補助的な手段)
WSL内で以下を実行すると、ページキャッシュを即座に解放できる。
sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
恒常的な対策にはならないが、一時的にメモリを空けたい場合に有効。
設定反映の確認方法
WSL内で free -h を実行し、total が設定値と一致しているか確認する。
$ free -h
total used free shared buff/cache available
Mem: 19Gi 727Mi 18Gi 18Mi 961Mi 18Gi
Swap: 2.0Gi 0B 2.0Gi
total: 19Gi(memory=20GBに対してカーネル等のオーバーヘッドで約1GB少ない)で正常。
補足: WSL2のファイルシステム構造
WSL2には2つのファイルシステムがある:
| パス | 実体 | I/O速度 |
|---|---|---|
/home/<user>/ |
WSL2のLinuxネイティブディスク | 高速 |
/mnt/c/ |
WindowsのCドライブをマウント | 低速(ブリッジ経由) |
開発用のソースコードは /home/<user>/ 以下に置くのが正解。/mnt/c/ はWindows↔Linux間のファイルシステムブリッジを経由するため、I/Oが大幅に遅くなる。
再発時のチェックリスト
- タスクマネージャーで
VmmemWSLのメモリ使用量を確認 - 異常にメモリを消費していれば
wsl --shutdownで再起動 -
.wslconfigの設定が反映されているかfree -hで確認 - 頻発する場合は
memory値の引き下げ、またはautoMemoryReclaim=dropcacheへの変更を検討