目的
表題の通りです。
開発を行っているとローカルでは問題なく動いていましたが、デプロイなど環境が変わると動かなくなることがよくあります。
環境と発生したエラーは以下です。
- Heroku
- Basicプラン
- Nest.js
Memory quota exceeded
Error R14 Heroku
容量が大きいデータを処理する際に発生し、エラーメッセージの内容からメモリの使用量について調査しました。
記事で紹介するコマンドはそのメモ書です。
コマンド
以下のコマンドで取得できます。
node -e "
const os = require('os');
const fs = require('fs');
const v8 = require('v8');
console.log('=== システム全体のメモリ情報 ===');
console.log(\`全体メモリ: \${(os.totalmem() / 1024 / 1024).toFixed(2)} MB\`);
console.log(\`使用メモリ: \${((os.totalmem() - os.freemem()) / 1024 / 1024).toFixed(2)} MB\`);
console.log(\`空きメモリ: \${(os.freemem() / 1024 / 1024).toFixed(2)} MB\`);
console.log(\`使用率: \${((1 - os.freemem() / os.totalmem()) * 100).toFixed(2)}%\`);
console.log('\n=== コンテナのメモリ制限情報 ===');
try {
const cgroupPaths = ['/sys/fs/cgroup/memory/memory.limit_in_bytes', '/sys/fs/cgroup/memory.max', '/proc/self/cgroup'];
let containerMemoryLimit;
for (const path of cgroupPaths) {
try {
const content = fs.readFileSync(path, 'utf8');
const limit = parseInt(content);
if (!isNaN(limit) && limit > 0) {
containerMemoryLimit = limit;
break;
}
} catch (err) {
continue;
}
}
if (containerMemoryLimit) {
console.log(\`コンテナメモリ制限: \${(containerMemoryLimit / 1024 / 1024).toFixed(2)} MB\`);
} else {
console.log('コンテナメモリ制限が設定されていません');
}
} catch (error) {
console.log('コンテナのメモリ制限情報を取得できませんでした:', error.message);
}
console.log('\n=== Node.jsのメモリ情報 ===');
const heapStats = v8.getHeapStatistics();
const used = process.memoryUsage();
console.log(\`全体メモリ制限: \${(heapStats.heap_size_limit / 1024 / 1024).toFixed(2)} MB\`);
console.log(\`メモリ使用量: \${(used.heapUsed / 1024 / 1024).toFixed(2)} MB\`);
console.log(\`メモリ割り当て量: \${(used.heapTotal / 1024 / 1024).toFixed(2)} MB\`);
console.log(\`空きメモリ: \${((heapStats.heap_size_limit - used.heapUsed) / 1024 / 1024).toFixed(2)} MB\`);
console.log(\`使用率: \${((used.heapUsed / heapStats.heap_size_limit) * 100).toFixed(2)}%\`);
"
結果割り当て
Node.jsのメモリがコンテナに割り当てられたメモリよりも大きいことがわかります。
Node.jsで使用するメモリ量を変更すれば解決しそうです。
=== システム全体のメモリ情報 ===
全体メモリ: 63276.48 MB
使用メモリ: 27747.42 MB
空きメモリ: 35529.06 MB
使用率: 43.85%
=== コンテナのメモリ制限情報 ===
コンテナメモリ制限: 512.00 MB
=== Node.jsのメモリ情報 ===
全体メモリ制限: 4144.00 MB
メモリ使用量: 3.86 MB
メモリ割り当て量: 4.45 MB
空きメモリ: 4140.14 MB
使用率: 0.09%
ローカル環境では以下となっています。
コンテナのメモリ上限を1024MBに指定
Node.jsには524MBが割り当てられています。
=== システム全体のメモリ情報 ===
全体メモリ: 7938.84 MB
使用メモリ: 2215.38 MB
空きメモリ: 5723.46 MB
使用率: 27.91%
=== コンテナのメモリ制限情報 ===
コンテナメモリ制限: 1024.00 MB
=== Node.jsのメモリ情報 ===
全体メモリ制限: 524.00 MB
メモリ使用量: 3.68 MB
メモリ割り当て量: 4.27 MB
空きメモリ: 520.32 MB
使用率: 0.70%
おわり
現象の解決などはコマンドとは別件なので割愛します。
エラー内容がメモリに関係するものであれば本記事のコマンドを使ってみると原因がわかるかもしれません。
どこに行ってもリソースに悩んでいる気がします。