Node.jsの--max-old-space-sizeのデフォルト値はメモリサイズによって変わりそう
背景
64bit環境ではNode.jsの--max-old-space-sizeのデフォルト値が1400MiBに制限されていると記載されている記事がいくつか見つかりましたが、ローカルのM1 MacのNode.jsのプロセスが--max-old-space-sizeを指定していないのに、明らかに1400MiB以上使っているため、疑問に思って調べてみました。
環境
Mac M1 32GB
調査
オプションを指定せずにNode.jsを起動し、V8のヒープサイズ制限を確認してみます。
❯ node -e 'console.log(Math.floor(v8.getHeapStatistics().heap_size_limit/1024/1024))'
4144
4144MBが設定されています。
ヒープメモリ関連のコードを追うと以下のロジックが見つかりました(全体のソースコードは把握できていないです)
64ビットシステムかつメモリが15GB以上であればヒープサイズを2GBから4GBに増やしているようです。このロジックの挙動になっていれば4144MBが設定されているのも辻褄が合いそうです。
検証
上記のロジックの挙動になっているか簡単に確認してみます。
multipassで16GB,8GBの仮想マシンを起動してNode.jsを実行してみます。
multipass launch --memory 8GB --name test1
multipass launch --memory 16G --name test2
8GBメモリ
node -v
v22.14.0
cat /proc/meminfo | grep MemTotal
MemTotal: 8110704 kB
node -e 'console.log(Math.floor(require("v8").getHeapStatistics().heap_size_limit / 1024 / 1024) + " MB")'
2096 MB
デフォルト値は2096MBが設定されています。
16GBメモリ
node -v
v22.14.0
cat /proc/meminfo | grep MemTotal
MemTotal: 16339536 kB
node -e 'console.log(Math.floor(require("v8").getHeapStatistics().heap_size_limit / 1024 / 1024) + " MB")'
4144 MB
デフォルト値は4144MBが設定されています。
最後に
今回の検証で物理メモリによって--max-old-space-sizeが動的に割り当てられることが分かりました。以前、GitHub Actions上でheap out of memoryのエラーが発生し、ローカルでは問題ないのになぜ?(どちらも1400MiBに割り当てられているならローカルも落ちるはずでは?)と思うことがありましたGithub Actionsの方がメモリが少なく、--max-old-space-sizeが少なめに割り当てられていたから落ちていたのかなと納得できました。
この調査では一部のソースコードしか確認できていないため、もし誤りがあればご指摘いただけるとありがたいです。
参考記事
Discussion