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

以前、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 までご連絡ください。
Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソースPython vs. JavaScript:コミュニティ、ライブラリ、リソースApr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

See all articles

ホット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ヘンタイを無料で生成します。

ホットツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。