Help us understand the problem. What is going on with this article?

WSL2によるホストのメモリ枯渇を防ぐための暫定対処

5/27にWindows 10 2004 Updateが正式リリースされて、それに伴いWSL2もWindows Insider Preview版を使用しなくても利用可能となりました:tada:

しかしWSL2を使用してるとVmmemというプロセスのメモリ使用量が増加し続けて、Windowsホストのメモリが枯渇してしまう問題があります。そしてこの問題は正式リリース後も解消されず残っています。

NOTE: Windowsホストで動いているVmmemプロセスで「WSL2のHypver-V仮想マシン全体が消費&確保しているCPUとメモリ」を確認できるという大雑把な理解でOKです。

microsoft/WSLのIssueは1年近くOpenのままとなっており、Microsoft側も問題を認識して取り組んでいるものの未だに根本対処されていません。

https://github.com/microsoft/WSL/issues/4166

本問題のアップデート情報 (順次追記: 7/15追記)

本問題に関する重要なアップデート情報はここに追記する予定です。
なお本問題が根本的に解決されたタイミングで更新時に変更通知を送る予定です。

  • 2020/07/15 - 特に表立った動きなし。
    • 6/25頃に開発者が対処を盛り込んだPRがある(comment)と発言しているため対応は進んでいる可能性が高い。
    • 7/7頃にIssueが荒らされたことにより、Issueがロックされた状態となっている。
  • 2020/06/03 - WSL開発メンバが本問題の原因がLinuxファイルキャッシュによるものであること(Link)、暫定対処がメモリサイズの固定化であること(Link)、本問題を現在対処中であること(Link)をTwitterに投稿しています。

結論: 暫定対処でメモリサイズを固定する

WSL2のメモリサイズを固定することでWindowsホストのメモリ枯渇を防ぎます。
原因について興味がある人は後述しているのでそちらを参照してください。

%USERPROFILE%\.wslconfigのコンフィグに以下の設定を行います。

  • %USERPROFILE%C:\Users\taroのようなホームディレクトリを指します。
  • コンフィグが存在しない場合は作成してください。
  • 設定した後はWSL2を再起動するか、OSを再起動してください。
[wsl2]
memory=6GB
swap=0
  • memoryにはWSL2が最大確保するメモリサイズを指定します。PCの搭載メモリとWSL2の使用用途に応じてメモリサイズの値は変更してください。ちなみに未指定時のデフォルト値はPC搭載メモリの80%です。
  • (個人的に推奨) swapを0に設定してスワップを無効にします。
    • スワップを無効にするとWSL2側で実際にメモリ不足になった途端に変な挙動を起こすかもしれません。しかしその代わりSSD等で大量のスワップIn/Outの発生を防ぐため、大量書き込みによるSSDの寿命を縮めることは回避できます。トレードオフを意識して設定するかどうかを考えましょう。

メモリサイズの上限を設定しなくてもいい感じに使えるのがWSL2の利点の一つだと考えているので、この暫定対処は心苦しいですが致し方ないところです。早く何らかの形で改善してほしいものです。

何が原因か?

Issueの中では、以下のLinuxとWSL2の特性が相まって問題を引き起こしてることが指摘されてます。

  • Linuxでは積極的にファイルアクセス時にファイルキャッシュをメモリ上に配置する(freeコマンドにおけるbuff/cache使用量の増加)。ファイルを削除したり、プロセス等がメモリを確保できなくなるくらいにメモリ不足になるまでは基本的にファイルキャッシュは確保したまま。
  • WSL2は仮想マシン上のLinuxのメモリ使用量に応じて、仮想マシンのメモリサイズを動的に増減させる。
    • 当然ですが仮想マシンのメモリサイズはLinuxのメモリ使用量よりも多く確保します。

それぞれの特性により、開発等の時の大量のファイル、ライブラリ、DockerイメージなどにアクセスするとLinuxのファイルキャッシュを中心に大量のメモリを確保し、それに合わせてWSL2が仮想マシンのメモリサイズを増加させていきます。WSL2が仮想マシンのメモリサイズを増加させるため、Linuxでは「まだメモリに余裕がある」と判断してファイルキャッシュをさらにため込んでという悪循環を引き起こします。

これによってメモリ16GB搭載のPCはもちろんメモリ32GB搭載のPCでも比較的簡単にWindowsホストのメモリが枯渇することになります。

以下はWSL2のメモリサイズを6GB固定にした環境でのVmmemおよびLinuxのメモリ使用量です。Linuxのメモリ使用量はfreeコマンドの結果で確認しています。大まかな目安として参考にしてください。

# - Vmmemメモリ使用量=3.5GBの時のWSL2のLinxuメモリ使用量
# - Linuxメモリ使用量=3.1GB(内、buff/cache使用量が2.6GB)
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           5.8G        479M        2.7G        1.2M        2.6G        5.1G

# - Vmmemメモリ使用量=1.7GB
# - Linuxメモリ使用量=0.6GB(内、buff/cache使用量が183MB)
$ free -h
              total        used        free      shared  buff/cache                 total        used        free      shared  buff/cache   available
Mem:           5.8G        457M        5.2G        1.2M        183M        5.2G

本問題が起きやすいユースケース

以下のユースケースではホストのメモリ枯渇が発生しやすいです。特にこれらのユースケースが組み合わさると本問題はより発生しやすくなります。

  • Visual Studio Code + Remote Extension(WSL)を使用してる
  • Docker Desktop WSL2を使用してる
  • 大きなコードベースで開発してる

上記の組み合わせが「Windows上でのUnix/Linux環境開発」の主流の一つになる可能性が高いですが、その組み合わせが本問題を引き起こしやすいというのは皮肉なものです。

その他の暫定対処方法

WSL2のメモリサイズを固定しない暫定対処について紹介します。
いずれも手動で実行する必要があり、自動運用するためには何らかの工夫が必要となるため積極的にはお勧めしません。

キャッシュをドロップ

基本的にメモリサイズ固定が最も効果的ですが、メモリサイズを可変のままにしたい場合は定期的にLinuxのキャッシュをドロップすることである程度は症状を抑えることもできます。

sudo sh -c "echo 3 >'/proc/sys/vm/drop_caches' && swapoff -a && swapon -a"

ただし、WSL2ではsystemdやcronなどが稼働していないため、そのあたりの準備が必要なことを考えるとメモリサイズ固定が一番手軽です。

WSL2を再起動

以下のURLの情報を参考にWSL2を一度再起動すれば、WSL2の仮想マシンがファイルキャッシュ等がクリアされた状態で立ち上がります。

WSL を再起動する方法

ちなみにWSLの再起動などの操作についてはWSL1もWSL2も基本的に同じです。

参考URL

WSL2やLinuxのメモリ管理などについて少し踏み込みたい人向けの参考URLが中心です。
(コメント欄でいただいたものも追記してます)

yoichiwo7
秋葉原の某所でエンジニアとして働いてます。 開発ワークフロー改善、およびKubernetes等のインフラ関連の技術にハマってます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした