目次
Hello world
ホームページ ウェブフロントエンド jsチュートリアル NodeJsのメモリリーク問題の詳しい説明

NodeJsのメモリリーク問題の詳しい説明

Jan 04, 2017 pm 04:55 PM

以前、NODE_ENV !=production で React がサーバー上でレンダリングされているときに、メモリ リークが発生することを偶然発見しました。特定の問題: https://github.com/facebook/react/issues/7406。ノード、リアクト同型性およびその他のテクノロジの普及に伴い、ノード側のメモリ リークなどの問題に注目が集まるはずです。ノードがメモリ リークを起こしやすい理由と、メモリ リークが発生した後のトラブルシューティング方法を以下に簡単に説明し、例を示します。

まず、ノードは v8 エンジンに基づいており、そのメモリ管理方法は v8 と一致しています。以下に、v8 に関連するメモリ効果を簡単に紹介します。

V8 のメモリ制限

node は V8 に基づいて構築されており、V8 を通じて js オブジェクトの割り当てと管理を行います。 V8 にはメモリの使用に制限があります (旧世代のメモリは 64 ビット システムで約 1.4G、32 ビット システムでは約 0.7G、64 ビット システムの新世代メモリは約 32MB、32 ビット システムでは約 0.7G) 16MB)。このような制限の下では、大きなメモリ オブジェクトを操作できません。誤ってこの制限に達すると、プロセスは終了します。

理由: V8 はガベージ コレクションの実行時に JavaScript アプリケーション ロジックをブロックし、ガベージ コレクションが完了するまで JavaScript アプリケーション ロジックを再実行します。この動作は「stop-the-world」と呼ばれます。 V8 のヒープ メモリが 1.5GB の場合、V8 が小規模なガベージ コレクションを実行するには 50 ミリ秒以上かかり、非増分ガベージ コレクションを実行するには 1 秒以上かかります。

ノード --max-old-space-size=xxx (単位 MB)、ノード --max-new-space-size=xxx (単位 KB) を通じて新世代のメモリと古い世代のメモリを設定し、デフォルトのメモリを破ります限界。

V8 ヒープの構成

V8 ヒープは、実際には古い世代と新しい世代だけで構成されているわけではありません。

新世代のメモリ領域: ほとんどのオブジェクトがここに割り当てられています。この領域は小さいですが、ガベージ コレクションは特に頻繁に行われます。

旧世代のポインター領域: この領域には、他のオブジェクトへのポインターを持つ可能性のあるほとんどのオブジェクトが含まれます。

旧世代のデータ領域:古い世代に属し、元のデータ オブジェクトのみがここに保存されます。これらのオブジェクトには他のオブジェクトへのポインターがありません。

サイズが他の領域のサイズを超えるオブジェクトが保存される場所です。独自のメモリ。ガベージ コレクションは大きなオブジェクトを移動しません。

コード領域: コード オブジェクト、つまり JIT 後の命令を含むオブジェクトがここに割り当てられます。実行許可を持つ唯一のメモリ領域

Cell領域、属性Cell領域、Map領域:Cell、属性Cell、Mapを格納する各領域は同じサイズの要素を格納し、単純な構造を持っています

GCリサイクル型

式 GC

は、ガベージ コレクターがメモリ空間をスキャンするときにガベージを収集 (増加) し、スキャン サイクルの終了時にガベージを空にするかどうかを示します。

非増分 GC

非増分ガベージ コレクターを使用する場合、ガベージは収集されるとすぐに空になります。

ガベージコレクタは、新世代のメモリ領域、旧世代のポインタ領域、旧世代のデータ領域に対してのみガベージコレクションを実行します。オブジェクトはまず、占有スペースの少ない新世代のメモリに格納されます。ほとんどのオブジェクトはすぐに期限切れになるため、非増分 GC はこれらの少量のメモリを直接再利用します。一部のオブジェクトが一定期間内にリサイクルできない場合、それらは古い世代のメモリ領域に移動されます。この領域では、インクリメンタル GC が頻繁に実行されず、時間がかかります。

では、メモリリークはいつ発生するのでしょうか?

メモリリークの経路

メモリリーク

キャッシュ

キューの消費がタイムリーではない

スコープが解放されていない

Nodeのメモリ構成は主にV8を通じて割り当てられた部分とNode自体によって割り当てられた部分です。 V8 のガベージ コレクションの主な制限は、V8 のヒープ メモリです。メモリ リークの主な理由: 1. キャッシュ、2. キューの消費がタイムリーではない、3. スコープが解放されていない。 : プロセスの常駐メモリ部分

heapTotal、heapused: V8 ヒープ メモリ情報

システム メモリ使用量 (単位バイト) を表示

os.totalmem()

os.freemem()

合計システム メモリを返し、アイドルメモリ

ガベージコレクションログを表示

node --trace_gc -e "var a = []; for( var i = 0; i gc.log //ガベージコレクションログを出力します

node --prof //ノードの実行パフォーマンスログを出力します。 表示するには、windows-tick.processor を使用します。



分析および監視ツール

v8-profilerは、v8ヒープメモリのスナップショットをキャプチャし、CPUを分析します

node-heapdumpは、v8ヒープメモリのスナップショットをキャプチャします

node-mtraceはスタック使用量を分析します

node-memwatchはガベージコレクションを監視します

node- memwatch

process.memoryUsage();
  {
    ress: 47038464, 
    heapTotal: 34264656, 
    heapUsed: 2052866 
  }
ログイン後にコピー


stats イベント: フルヒープ ガベージ コレクションが実行されるたびに、stats イベントがトリガーされます。このイベントはメモリ統計を提供します。

memwatch.on('stats',function(info){
  console.log(info)
})
memwatch.on('leak',function(info){
  console.log(info)
})
ログイン後にコピー


num_full_gc と num_inc_gc を観察して、ガベージ コレクションの状況を反映します。

リーク イベント: ガベージ コレクションを 5 回連続して実行してもメモリがまだ解放されない場合、メモリ リークが発生していることを意味します。このとき、リークイベントがトリガーされます。

りー

Heap Diffing 堆内存比较 排查内存溢出代码。
下面,我们通过一个例子来演示如何排查定位内存泄漏:

首先我们创建一个导致内存泄漏的例子:

//app.js
var app = require('express')();
var http = require('http').Server(app);
var heapdump = require('heapdump');
 
var leakobjs = [];
function LeakClass(){
  this.x = 1;
}
 
app.get('/', function(req, res){
  console.log('get /');
  for(var i = 0; i < 1000; i++){
    leakobjs.push(new LeakClass());
  }
  res.send(&#39;<h1 id="Hello-nbsp-world">Hello world</h1>&#39;);
});
 
setInterval(function(){
  heapdump.writeSnapshot(&#39;./&#39; + Date.now() + &#39;.heapsnapshot&#39;);
}, 3000);
 
http.listen(3000, function(){
  console.log(&#39;listening on port 3000&#39;);
});
ログイン後にコピー

   

这里我们通过设置一个不断增加且不回被回收的数组,来模拟内存泄漏。

通过使用heap-dump模块来定时纪录内存快照,并通过chrome开发者工具profiles来导入快照,对比分析。

我们可以看到,在浏览器访问 localhost:3000 ,并多次刷新后,快照的大小一直在增长,且即使不请求,也没有减小,说明已经发生了泄漏。

NodeJsのメモリリーク問題の詳しい説明

接着我们通过过chrome开发者工具profiles, 导入快照。通过设置comparison,对比初始快照,发送请求,平稳,再发送请求这3个阶段的内存快照。可以发现右侧new中LeakClass一直增加。在delta中始终为正数,说明并没有被回收。

NodeJsのメモリリーク問題の詳しい説明

小结

针对内存泄漏可以采用植入memwatch,或者定时上报process.memoryUsage内存使用率到monitor,并设置告警阀值进行监控。

当发现内存泄漏问题时,若允许情况下,可以在本地运行node-heapdump,使用定时生成内存快照。并把快照通过chrome Profiles分析泄漏原因。若无法本地调试,在测试服务器上使用v8-profiler输出内存快照比较分析json(需要代码侵入)。

需要考虑在什么情况下开启memwatch/heapdump。考虑heapdump的频度以免耗尽了CPU。 也可以考虑其他的方式来检测内存的增长,比如直接监控process.memoryUsage()。

当心误判,短暂的内存使用峰值表现得很像是内存泄漏。如果你的app突然要占用大量的CPU和内存,处理时间可能会跨越数个垃圾回收周期,那样的话memwatch很有可能将之误判为内存泄漏。但是,这种情况下,一旦你的app使用完这些资源,内存消耗就会降回正常的水平。所以需要注意的是持续报告的内存泄漏,而可以忽略一两次突发的警报。

更多NodeJsのメモリリーク問題の詳しい説明相关文章请关注PHP中文网!


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? 独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? Mar 18, 2025 pm 03:12 PM

記事では、JavaScriptライブラリの作成、公開、および維持について説明し、計画、開発、テスト、ドキュメント、およびプロモーション戦略に焦点を当てています。

ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? Mar 18, 2025 pm 03:14 PM

この記事では、ブラウザでJavaScriptのパフォーマンスを最適化するための戦略について説明し、実行時間の短縮、ページの負荷速度への影響を最小限に抑えることに焦点を当てています。

フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? Apr 04, 2025 pm 02:42 PM

フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:16 PM

この記事では、ブラウザ開発者ツールを使用した効果的なJavaScriptデバッグについて説明し、ブレークポイントの設定、コンソールの使用、パフォーマンスの分析に焦点を当てています。

誰がより多くのPythonまたはJavaScriptを支払われますか? 誰がより多くのPythonまたはJavaScriptを支払われますか? Apr 04, 2025 am 12:09 AM

スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

ソースマップを使用して、マイナイドJavaScriptコードをデバッグするにはどうすればよいですか? ソースマップを使用して、マイナイドJavaScriptコードをデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:17 PM

この記事では、ソースマップを使用して、元のコードにマッピングすることにより、Minified JavaScriptをデバッグする方法について説明します。ソースマップの有効化、ブレークポイントの設定、Chrome DevtoolsやWebpackなどのツールの使用について説明します。

Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Apr 04, 2025 pm 05:12 PM

Console.log出力の違いの根本原因に関する詳細な議論。この記事では、Console.log関数の出力結果の違いをコードの一部で分析し、その背後にある理由を説明します。 �...

JavaScriptを使用して、同じIDを持つArray要素を1つのオブジェクトにマージする方法は? JavaScriptを使用して、同じIDを持つArray要素を1つのオブジェクトにマージする方法は? Apr 04, 2025 pm 05:09 PM

同じIDを持つ配列要素をJavaScriptの1つのオブジェクトにマージする方法は?データを処理するとき、私たちはしばしば同じIDを持つ必要性に遭遇します...

See all articles