Nodejs のメモリ管理手順の詳細な説明

php中世界最好的语言
リリース: 2018-05-22 09:21:10
オリジナル
1423 人が閲覧しました

今回は、Nodejs のメモリ管理の手順について詳しく説明します。Nodejs のメモリ管理の 注意事項 は何ですか?実際のケースを見てみましょう。

は異なるホスト環境で実行され、それに対応するメモリ管理の要件も異なります。ホスト環境がブラウザの場合、Web ページの実行時間は短く、ユーザーのマシン上でのみ実行されるためです (分散型と同等)。 )、メモリが過剰に使用されたり、特定のメモリ リークが発生したりしても、エンド ユーザーには大きな影響はありません。ホスト環境を使用してサーバー (ノード) をプログラムする場合、コード自体が少数の固定マシン (集中型) で実行され、メモリ管理が適切でないと実行時間が長くなります。メモリの拡張が発生すると、メモリ リークが発生した場合でも、サーバー側の応答時間が長くなったり、サービスがクラッシュしたりすることがあります。

NodejsはV8をベースに構築されているため、Node(Bufferではありません)で使用されるJavaScriptオブジェクトは基本的にV8を通じて割り当て、管理されます。 V8 では、占有メモリ サイズに制限が設けられています (64 ビット オペレーティング システムの場合、単一ノード プロセスで使用できる最大ヒープ メモリ サイズは約 1.5 GB)。サーバーに大きなメモリが搭載されている場合でも、V8 のこの制限により、Node はサーバーのリソースを完全に活用できません。それにしても、なぜV8にはこのような制限があるのでしょうか?この制限の理由は、実際にはガベージ コレクション メカニズムに関連しており、1.5 GB のガベージ コレクション ヒープ メモリ ヒープを例に挙げると、V8 では小さなガベージ コレクションを実行するのに 50 ミリ秒以上かかり、完全なガベージ コレクションを実行するのに 1 秒以上かかる場合もあります。リサイクル処理中は JavaScript スレッドが一時停止状態になる必要があるため、V8 ではバックエンド サービスのパフォーマンスに大きな影響を与えます。ヒープメモリには制限があります。それでも、V8 はヒープ メモリ サイズ (--max-old-pace-size) をカスタマイズする方法を提供しています。ここで、old-space は古い世代を表し、new-space は新しい世代を表します。

node --max-old-space-size=xxx index.js //单位为MB
// 之前还可以通过-max-new-space-size来定义新生代堆大小,现在已经不可以了
ログイン後にコピー

メモリ リークが原因でサーバーが頻繁に再起動し続ける場合は、問題を特定する時間を稼ぐために、まずヒープ メモリ サイズを増やすことをお勧めします。結局のところ、サービスの応答が遅い方が、エラー ページを直接返すよりもユーザーにとっては良いのです。

なぜ古い世代と新しい世代が必要なのでしょうか?

世代別ガベージ コレクション メカニズムでは、古い世代と新しい世代は実際には異なる世代です。これは、すべてのシナリオに適したガベージ コレクション アルゴリズムはなく、最良の結果を達成するには、オブジェクトのライフ サイクルが異なると実際に異なるリサイクル戦略が必要になるためです。 V8 では世代別ガベージ コレクション メカニズムが採用されており、オブジェクトは生存時間に応じて異なる世代に分割され、より適切で優れたアルゴリズムが異なる世代 (新世代、旧世代) のメモリに適用されます。

新世代のオブジェクトの生存時間は短くなりますが、古い世代のオブジェクトの生存時間は長くなり、メモリ内に常駐することもあります。これに基づいて設計された新世代のメモリは、一般に旧世代のメモリよりも大幅に小さくなります。V8 の新世代の最大メモリは 32​​M (例として 64 ビット システム)、旧世代の最大メモリです。世代は1400MBです。 V8 で使用される実際のヒープ メモリ サイズは、新世代と旧世代で使用されるメモリの合計 (1432MB) ですが、実際には、V8 の最大値は使用メモリ ペア サイズよりも 32M (1464MB) 大きくなります。新世代でガベージコレクションを行うにはどうすればよいでしょうか?

新世代では、Scavenge と呼ばれるガベージ コレクション アルゴリズムが使用されます。 Scavenge の具体的な実装では、主に Cheney アルゴリズムが使用されます。Cheney アルゴリズムは、新世代ヒープを 2 つに分割し、1 つは使用 (半空間から)、もう 1 つは空き (半空間へ) に分割します。 オブジェクトの作成時

は、Fromスペースに割り当てられるようになりました。ガベージコレクションが必要な場合、Fromスペースに残っているオブジェクトがチェックされ、同時にToスペースにコピーされます。 From スペースがクリアされ、From と To が Exchange になり、ガベージ コレクション プロセス全体で、2 つのセイスペース間で残っているオブジェクトがコピーされます。ライフ サイクルが短いシナリオでは、存続するオブジェクトがオブジェクト全体に占める割合は比較的小さいため、Scavenge は存続するオブジェクトのコピーを使用しますが、Scavenge はヒープ メモリ領域の半分しか使用できません。これは、時間とスペースを交換する典型的な例です。 。

当一个对象经过多次垃圾回收依然存活的话,就会被认为是生命周期较长的对象,一方面新生代堆比较小,另一方面重复复制生命周期长的对象也很没有效率,所以对于生命周期长的对象会被移到老生代中去。新生代对象移动到老生代有两个对象:1.对象是否是生命周期较长的对象(已经经历过垃圾回收)2.To空间使用占比是否超过了25%。限制25%的原因是由于垃圾回收完成后To会变成From,如果不做限制的话可能会出现From很快被用光的情况,出现频繁的垃圾回收,也会影响效率。

老生代如何做垃圾回收?

老生代由于存活对象占较大比重,不适合对存活对象进行操作,使用Scavenge算法就不太合适了,因此老生代采用了Mark-Sweep和Mark-Compact相结合的方式。

Mark-Sweep分为标记和清除两个阶段,在标记阶段遍历堆中所有对象,标记活着的对象,然后在清除阶段未被标记的对象将会被清除掉。Mark-Sweep解决了内存释放的问题但是由于没有像Scavenge那样复制对象的操作导致内存碎片化不连续。而Mark-Compact就是用来解决内存碎片化问题的。Mark-Compact会将存活的对象往一端移动,移动完成后直接清理掉边界外的内存,这样就有大段的连续可用内存了,但是由于涉及到对象的移动,因此Mark-Compact的速度要比Mark-Sweep慢了。V8主要使用Mark-Sweep,只有当空间不足以对新生代中今生过来的对象进行分配时才使用Mark-Compact。

垃圾回收过程中会导致应用程序暂停执行,由于新生代本身空间较小,且要复制的存活对象占比也少,因此即便执行全量垃圾回收也影响不大,但是老生代空间很大,存活对象也多,执行一次全量垃圾回收对于应用程序暂停会是一个比较长的时间,因此V8将老生的标记改成了增量更新的方式,使得标记和应用程序交替执行直到标记完成,然后垃圾回收再执行后面的清理工作。注意清理工作并不是增量的。

开发者可以指定强制垃圾回收吗?

答案是可以了,在启动node服务的时候使用--expose-gc flag

$ node --expose-gc file.js
ログイン後にコピー

这样全局对象上就有了执行垃圾回收的函数

global.gc();
ログイン後にコピー

推荐更安全的写法

function forceGC()
 if (global.gc) {
  global.gc();
 } else {
  console.warn('No GC hook! Start your program as `node --expose-gc file.js`.');
 }
}
ログイン後にコピー

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Vue页面骨架屏注入步骤详解

解决node修改后需频繁手动重启如何处理

以上がNodejs のメモリ管理手順の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!