web-dev-qa-db-ja.com

node.jsを使用したHerokuエラーR14(メモリ割り当て超過)

ノードアプリが1日ほどでメモリ不足になることに気付きました。メモリは、毎分実行されるジョブによって消費されます。これは、現在行われていることのほとんどです。アプリを自分のマシンでローカルに実行すると、アプリがメモリの上限に達し、ガベージコレクションがジャンプするのがわかります。

Herokuでは、1G RAM=インスタンスのメモリ上限を超えており、GCが起動していません。ノードが実際のDynoよりも高いメモリ制限で構成されているためかと思います。

言い換え:herkouのnode.jsメモリー制限は、Dynoメモリー制限にバインドされていますか?

7
Stan Wiechers

こちらがherokuからの返事です。構成を変更する必要があり、すぐに使える構成を使用できないようです

こんにちはスタン、

これらのドキュメントにリンクしていただきありがとうございます。私は最近おしゃべりなWEB_CONCURRENCY出力をサイレントにしたので、そのターミナルの例を更新する必要があります。この機能を大幅に追加したときにロギングを追加したので、これらの新しい変数が環境に侵入しても驚かないようになっています。

アプリの値を確認するには、次を実行します。

$ heroku run 'echo $ WEB_MEMORY、$ WEB_CONCURRENCY'ただし、これらの値は、クラスター化されたノードアプリが実行する同時プロセスの数を決定するためにのみ存在し、さらに、WEB_CONCURRENCY値を使用することを選択した場合のみあなたのコード。これらは、nodejs.org/distからダウンロードされた完全に標準のバニラバージョンである、ノードバイナリまたはそのデフォルトのメモリ割り当てまたはガベージコレクションにまったく影響しません。

https://devcenter.heroku.com/articles/node-concurrency#tuning-the-concurrency-level V8は、ガベージコレクションに貪欲でレイジーなアプローチを使用しています。さらに、V8はデフォルトで約1.5 GBの作業を想定しています(2X dynoの1 GBの制限を超える)。ノードのデフォルトのメモリ動作を変更したい場合は、いくつかのオプションがあります。

  • メモリが設定された制限を超えるたびに手動でGCをトリガーします( https://simonmcmanus.wordpress.com/2013/01/03/forcing-garbage-collection-with-node-js-and-v8/

  • Max_old_space_sizeをデフォルトよりも低く設定します(例:node --max_old_space_size = 960)。 v8ソースのいくつかのメトリックはmax_old_space_sizeに関連付けられているため、これによりgcをいくぶん積極的にすることができます。欠点は、1バイトでも値を超えると、プログラムがクラッシュすることです。

  • 常にグローバルなコレクションを強制するには、gc_globalをtrueに設定します(デフォルトではfalse-グローバルコレクションはデフォルトのマルチフェーズコレクションよりも遅いことに注意してください)。

  • Nolazy_sweepingをtrueに設定すると、GCが少し積極的になります。

単一ノードプロセスで約1 GBのメモリを超える場合、ベストプラクティスはそのプロセスを複数のワーカーに分割することです。

https://github.com/joyent/node/wiki/FAQ#what-is-the-memory-limit-on-a-node-process 乾杯、ハンター

6
Stan Wiechers