🌊

WSL2 + Docker をメモリを節約しながら使えるか

2021/04/21に公開

WSL2 + Docker という環境で、Chrome を開きながら、VScode でプログラミングしていると、メモリがめちゃくちゃ消費されてしまいます。常時メモリ使用率99%です。マウスもまともに動きません。これでは何も作業できないので、WSL2 + Docker の環境でメモリが節約できないか調べました。

結論から述べると、.wslconfig を書けばメモリの使用量を抑えられます。

以下調べ方や、対策など下に書いていきます。

環境について


windowsキー + r で winver を実行


メモリとCPU

メモリの使用状況を確認

下記の点でメモリの使用状況を確認します。

  • Windows 全体のメモリ
  • WSL2 が使用しているメモリ
  • WSL2 上の Ubuntu18.04 が使用しているメモリ
  • Docker / docker-compose が使用しているメモリ

Windows 全体のメモリ使用状況をタスクマネージャーで確認


※これは事後に撮ったもの。最初はメモリが99%になっていた

当初、Vmmem なるタスクが4G~5Gのメモリを専有していました。Vmmem は仮想環境で使用されているメモリとプロセッサを表しているものです。仮想環境とは、WSL2のことです。WSL2がメモリをめっちゃ使っていることがわかったので、WSL2のメモリ使用量が制限できるか調べました。

WSL2 が使用しているメモリを制限する

WSL2に関して、C:\Users\[username]\.wslconfig を書くことで、いろいろと設定が出来ます。メモリの使用量もこの設定ファイルで設定出来ます。

.wslconfig の書き方など詳細は wslのドキュメント で確認出来ます。

公式ドキュメントによると WSL2 は Windows上 で使用可能なメモリのうち最大80%を使用すると書いてあります。

50% of total memory on Windows or 8GB, whichever is less; on builds before 20175: 80% of your total memory on Windows

自分のPCにはもっと少ないメモリ量を .wslconfig に記載します。

.wslconfig
[wsl2]
memory=1GB

これが、WSL2 で使用できるメモリの最大値を設定する記述です。。
.wslconfig を作成・更新したら、wsl の再起動して、設定を反映させます。
参考: wsl2 再起動方法
wsl を再起動して、タスクマネジャーを見ると、vmmem が使用するメモリが 1020MB を超えなくなりました。

WSL2 上の Ubuntu18.04 のメモリを確認

WSL2 のメモリ割り当てを制限したあと、実際に WSL 上で使えるメモリが制限されるか確認してみました。

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           978M        201M         68M        325M        708M        314M
Swap:          1.0G         75M        948M

うーん、total が 6.1G、 free が 2.8G もあります。何より used が wsl2 の設定で制限している 1G を超える 1.5G になっているという・・・
※↑の free コマンドの内容を更新しました。.wslconfig を正しく書くことで、メモリの使用量が抑えられていることが確認できました。.wslconfig には [wsl2] を設定ファイルの最上部に記載する必要がありました。

Docker / docker-compose が使用できるメモリ量を制限する

Docker は基本的にメモリを無制限で使用します。

By default, a container has no resource constraints and can use as much of a given resource as the host’s kernel scheduler allows

引用元: https://docs.docker.com/config/containers/resource_constraints/#memory

WSL2では、Docker Desktop を使って Docker を動かすので、Docker Desktop の設定でメモリの使用量の制限ができるか調べました。Docker Desktop の機能としてメモリを制限する機能はなく、あくまで、WSL2 でメモリ使用量を制限するしか無いようです。

The Advanced tab is only available in Hyper-V mode, because in WSL 2 mode and Windows container mode these resources are managed by Windows. In WSL 2 mode, you can configure limits on the memory, CPU, and swap size allocated to the WSL 2 utility VM.

引用元: https://docs.docker.com/docker-for-windows/

調べてみると、docker-compose で起動するコンテナが使用するメモリを制限する設定があったのでそれはとりあえず入れました。mem_limit という設定です。下記のように、rails を動かすコンテナと db を動かすコンテナのメモリ上限をそれぞれ 500MB に設定しました。

docker-compose.yml
version: "2.4"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: hogehoge
    mem_limit: 500m
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    mem_limit: 500m

注意点として、version 2系でしか mem_limit の設定が使えません。 これで docker-compose up をして、メモリの確認をします。

$ docker stats junyablog_db_1 junyablog_web_1
CONTAINER ID   NAME              CPU %     MEM USAGE / LIMIT   MEM %     NET I/O         BLOCK I/O   PIDS
7bc5211e9318   blog_db_1    0.00%     20.05MiB / 500MiB   4.01%     5.49kB / 12kB   0B / 0B     7
73285e90db42   blog_web_1   0.02%     101.9MiB / 500MiB   20.37%    146kB / 726kB   0B / 0B     20

コンテナレベルで、メモリの上限が設定出来ました。

最終的に・・・

  • Windows 全体のメモリ
    • Vmmem がメモリをたくさん消費していた
    • Vmmem は wsl2 のメモリ・プロセッサを表す(wsl はデフォルト設定で最大PCの80%のメモリを使用する)
    • Vmmem が使用するメモリの最大値は、.wslconfig に記載する設定で制限できる
  • WSL2 が使用しているメモリ
    • .wslconfig で WSL2 が使用するメモリの最大値
  • WSL2 上の Ubuntu18.04 が使用しているメモリ
    • .wslconfig で設定されたメモリの最大値までしか使えないことが確認できた
  • Docker / docker-compose が使用しているメモリ
    • mem_limit でコンテナが使うメモリ量を制限できた

コンテナを起動して、Chrome で調べ物しながら、VScode でプログラミングをしても、メモリの使用率が 60% ~ 70% の間で落ち着くようになりました。

.wslconfig でメモリの最大値を設定してやることで、快適に開発できる環境になりました。

参考

https://www.youtube.com/watch?v=4PwClrUCqJM

Discussion