WSL2 + Docker をメモリを節約しながら使えるか
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
に記載します。
[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 に設定しました。
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
でメモリの最大値を設定してやることで、快適に開発できる環境になりました。
参考
Discussion