検索
ホームページウェブフロントエンドjsチュートリアル【体験談まとめ】Nodeのメモリリークのトラブルシューティング方法は?アイデアを共有する

ノードのメモリ リークをトラブルシューティングするにはどうすればよいですか?次の記事は、ノードのメモリ リークのトラブルシューティング体験をまとめたもので、皆様のお役に立てれば幸いです。

【体験談まとめ】Nodeのメモリリークのトラブルシューティング方法は?アイデアを共有する

Nodejs サーバーサイド開発のシナリオでは、メモリ リーク が間違いなく最も厄介な問題です。 しかし、プロジェクトが開発され反復され続ける限り、メモリ リークの問題は絶対に避けられず、遅かれ早かれ発生するだけです。したがって、効果的な メモリ リーク トラブルシューティング方法を体系的に習得することは、Nodejs エンジニアの最も基本的かつ中心的な能力です。

メモリ リークに対処する際の難しさは、無数の関数や関数の中から、どの行のどの関数や関数がメモリ リークの原因となっているのかを正確に特定する方法です。 残念ながら、現時点ではメモリ リークを簡単に特定できるツールは市場に存在しないため、この問題に初めて遭遇した多くのエンジニアは混乱し、対処方法がわからなくなるでしょう。 ここでは、22 年間に Memory Leak を調査した事例に基づいて、私の対処方法を共有します。

問題の説明

2022 Q4 ある日、研究開発ユーザー グループから、当社の研究開発プラットフォームにアクセスできないことが報告され、多数のユーザーがバックグラウンドで例外が発生しました。タスクは完了していません。 最初の反応は、メモリ リークの可能性があるということです。幸いなことに、サービスはモニタリング (prometheus grafana) に接続されています。grafana モニタリング パネルでは、 10.00 以降、メモリが制御不能になっていることが判明しました。明らかなデータ漏洩が発生しました。 [関連チュートリアルの推奨事項: nodejs ビデオ チュートリアル ]

DX 内存泄漏监控图.png

##手順 :

  • プロセス メモリ: rss (常駐セット サイズ)、プロセスの常駐メモリ サイズ。
  • heapTotal: V8 ヒープの合計サイズ。
  • heapused: 使用される V8 ヒープのサイズ。
  • external: V8 オフヒープ メモリの使用量。

Nodejs のグローバル メソッド process.memoryUsage() を呼び出して、heapTotal と # を含むこれらのデータを取得できます。 ##heapused は V8 ヒープの使用量であり、Node.js 内の JavaScript オブジェクトが保存される場所です。また、external は、C オブジェクトなど、非 V8 ヒープに割り当てられたメモリを表します。 rss は、プロセスの合計メモリ使用量です。一般に、監視データを確認するときは、heapused インジケーターに注目してください。

メモリ リークの種類

メモリ リークは主に 2 つに分類されます。 into:

グローバル リーク
  • ローカル リーク
実際には、グローバル メモリ リークであろうとローカル メモリ リークであろうと、すべてやるべきことは、除外範囲をできる限り狭めることです。

グローバル メモリ リーク

グローバル コンテンツ リークは通常、

ミドルウェア

および コンポーネント で発生します。このタイプのメモリ リークもトラブルシューティングが最も簡単です。 残念ながら、

2022 Q4

で発生したメモリ リークはこのタイプに属さないため、ローカル リークの考え方に従って分析する必要があります。

二分法によるトラブルシューティング

このタイプの他の科学的分析方法については説明しませんが、この場合、二分法を使用するのが最も早いと思います。

プロセス フロー

:

    最初にコードの半分をコメントアウトします (半分に減らします
  • ミドルウェア

    , コンポーネント、または他の一般的なロジックの使用)

  • インターフェイスを選択するか、ストレス テスト用の新しいテスト インターフェイスを作成します
  • Ifメモリリークが発生した場合、リークポイントは現在使用中のコード内にあり、リークがない場合、リークポイントは
  • に表示され、上記のプロセスを約 20 回繰り返します~ 60 分。メモリ リークは確実に特定できます。
の詳細な場所。2020 年に
Nuxt## ベースの SSR アプリケーションを開発していたときのことです。 # では、オンラインにする前のストレス テストでアプリケーション メモリ リークが見つかり、グローバルであることが判明しました。予期せぬリークの後、二分法を使用して問題を特定するのに約 30 分かかりました。

当時のリークの原因は、サーバー側で axios を使用していたためでしたが、その後、
axios を統合し、関連するものをすべて node- に置き換えました。 fetch で解決しました。それ以来、axios PDST に切り替えました。axiosNode サービスで使用することはありません。

永続的なメモリ リークの部分的なトラブルシューティング

ほとんどのメモリ リークはローカル リークです。リーク ポイントは、特定の ミドルウェア

または特定の # に存在する可能性があります。 ##interface

. 特定の 非同期タスク では、このような特性により、トラブルシューティングも困難になります。この場合、分析のために heapdump が実行されます。 <p>ここでは主にこの場合の私のアイデアについて話します。<code>heapdump の詳細な説明は次の段落

Heap Dump に記載します。 : ヒープ ダンプ。以下の部分はすべて heapdump で表されます。heapdump を実行するためのツールやチュートリアルは数多くあります (chrome、vscode、heapdump オープン ソース ライブラリなど)。私が使用するヒープダンプ ライブラリに関するオンライン チュートリアルは多数ありますが、ここでは説明しません。

ローカル メモリ リークのトラブルシューティングには、ある程度のメモリ リークのトラブルシューティングの経験が必要です。問題が発生するたびに、自分自身のテストとして扱ってください。経験を積んでから、メモリのトラブルシューティングを行うことができます。漏れの問題は後で発生しますが、それはますます速くなります。

1. メモリ リークが発生する時間範囲を特定する

これは非常に重要であり、これを知っておくと、調査の範囲が大幅に狭まる可能性があります。
この状況はよく発生します。この反復には 3 つの関数 A、B、C があり、ストレス テスト中またはオンラインになった後にメモリ リークが発生します。その後、直接ロックできるようになり、これら 3 つの新しい関数の間で小さなメモリ リークが発生します。この場合、heapdump を実行するために運用環境に移動する必要はありません。いくつかのツールを使用してローカルでメモリ リーク ポイントを簡単に分析し、特定することができます。

2020 年の Q4 における特殊な状況により、メモリ リークが見つかったとき、メモリ リークが最初に発生した時期を特定することが困難でした。大まかに 1 でロックすることしかできません。数か月以内に。今月もメジャーバージョンアップを行っているのですが、これらの機能やインターフェースを一つ一つチェックしていくと、かなりのコストがかかってしまいます。 したがって、さらに分析するには、より多くのデータを組み合わせる必要があります

2. ヒープダンプ データを収集します

  • 運用開始時ノード追加--expose-gc、このパラメータは gc() メソッドをグローバルに挿入して、GC の手動トリガーを容易にし、より正確な ヒープ スナップショットdata
  • ## を取得します。 # ここでは 2 つのインターフェイスを追加し、独自の排他的アクセス許可を取得しました。
    • GC を手動でトリガーします
    • #印刷ヒープ スナップショット
  • ヒープダンプ
  • #プロジェクト開始後の初めてのスナップショット データの印刷
      メモリが 100M 増加した後: 最初に GC をトリガーし、次に 2 回目にヒープ スナップショット データを印刷します
    • メモリがクリティカルに近づいています GC を再度トリガーして、ヒープ スナップショットを出力します
  • ヒープ スナップショット データを収集するときに特に注意が必要な点がいくつかあります。

ノード サービスは
heapdump
    中に中断されます。この時間は、その時点のサーバー メモリのサイズに応じて約 2 ~ 30 分になります。 。運用環境で
  • heapdump を実行するには、運用および保守と協力して合理的な戦略を策定する必要があります。ここでは、2 つのプライマリ pod とセカンダリ pod を使用します。プライマリ pod が停止すると、ビジネス リクエストは、本番稼働を確保するためにセカンダリ pod にロード バランシングされます。ビジネスの。 (このプロセスは運用保守と緊密に連携したプロセスである必要があります。結局のところ、heapdump もそれらを通じてサーバー内の heap snapshot ファイルを取得する必要があります)
  • クリティカル ポイントでスナップショットを印刷するというのは、漠然とした説明ですが、試したことがある方ならわかると思いますが、メモリ スナップショットを印刷する前にクリティカル ポイントのすぐ近くで待機すると、印刷されません。したがって、この程度に近づくには自分をコントロールする必要があります。
  • 少なくとも 3 回実行してください
  • heapdump(実際には、最も詳細なデータを取得するために 5 回実行しました)

3 . 分析のために監視パネルからのデータを結合します

監視にアクセスするにはアプリケーション サービスが必要です。ここでのアプリケーションは監視に

prometheus grafana を使用します。主にサービスの次の指標を監視します

    #QPS
  • (1 秒あたりのリクエスト訪問数)、リクエストのステータス、およびそのアクセス パス
  • ART
  • (インターフェイスの平均応答時間) とそのアクセス データ
  • NodeJs
  • バージョン
  • アクション ハンドラー
  • (ハンドル)# #イベント ループ ラグ
  • (イベント ラグ)
  • サービス プロセスの再起動数
  • CPU 使用率
  • メモリ使用量:
  • rss
  • ,
  • heapTotalheapusedexternalheapAvailableDetail
heapdump
データのみが含まれません。十分です、

heapdump データは非常に曖昧であり、視覚化ツールのサポートがあっても、問題を正確に特定することは困難です。今回はgrafanaのデータをいくつか組み合わせて見てみました。

私の解析・処理結果

当時のスナップショットデータが紛失してしまったので、ここでシーンをシミュレーションしてみます。

1.

grafana

モニタリング インターフェイスを通じて、メモリが増加していて減少していないことがわかりますが、同時に

の数が減少していることにも気づきました。サービス内のハンドル も急増していますが、落ちることはありません。

2. これは、リークが発生した月の新機能を確認し、メモリ リークは bull メッセージ キュー コンポーネントの使用によって引き起こされているのではないかと疑ったときのことです。まず、関連するアプリケーション コードを分析しましたが、メモリ リークを引き起こすような問題があるとはわかりませんでした。 1.のハンドルリークの問題と合わせると、bullを使用した後に特定のリソースを手動で解放する必要があるようですが、現時点では具体的な理由はわかりません。

3. 次に、5 回分の heapdunmp データを分析し、そのデータを chrome にインポートしました。5 回分のヒープ スナップショットを比較した結果、次のことがわかりました。各キューの作成後、 TCP 、 Socket 、 EventEmitter イベントは解放されません。現時点では、bull の不規則な使用が原因であることはほぼ確実です。 bull では、通常、キューは頻繁に作成されず、キューによって占有されているシステム リソースは自動的に解放されないため、必要に応じて手動で解放する必要があります。

【体験談まとめ】Nodeのメモリリークのトラブルシューティング方法は?アイデアを共有する

#4. コードを調整した後、再度ストレス テストを実行したところ、問題は解決しました。

ヒント: Nodejs の handle は、基礎となるシステム リソース (ファイル、ネットワーク接続など) を指すポインターです。ハンドルを使用すると、Node.js プログラムは、基盤となるシステムと直接対話することなく、これらのリソースにアクセスして操作できるようになります。ハンドルは、Node.js ライブラリまたはモジュールで使用されるハンドルの種類に応じて、整数またはオブジェクトになります。 CommonHandle:

  • #fs.open() 返されるファイル ハンドル
  • net.createServer() 返されるネットワーク サーバー ハンドル
  • dgram.createSocket() 返された UDP ソケット ハンドル
  • child_process.spawn() 返された子プロセス ハンドル
  • #crypto.createHash()
  • 返されたハッシュ ハンドル
  • zlib.createGzip()
  • 返された圧縮ハンドル
#ヒープダンプ分析の概要

通常、ヒープ スナップショット

データを初めて取得するときは、多くの人が混乱します。私も同様です。インターネット上で無数の分析テクニックを読み、それを私自身の実際の実践と組み合わせた後、さらに役立つテクニックをいくつかまとめました。一部の基本的な使用方法のチュートリアルについては、ここでは説明しません。ここでは、

chrome; 概要ビュー

データをインポートした後の画像の見方について主に説明します。このビューでは、通常、まず [保持サイズ] を選択し、次にオブジェクトのサイズと数を観察します。経験豊富なエンジニアは、特定のオブジェクトの数が異常であることをすぐに判断できます。このビューでは、自分で定義したいくつかのオブジェクトを考慮することに加えて、

【体験談まとめ】Nodeのメモリリークのトラブルシューティング方法は?アイデアを共有する

TCP
  • ##ソケット
  • など、メモリ リークが発生しやすい一部のオブジェクトにも注意が必要です。 EventEmitter
  • グローバル
  • 比較ビュー

合格した場合概要ビュー, 問題が特定できない場合は、通常、

Comparison

ビューを使用します。このビューを通じて、2 つのヒープ スナップショット内のオブジェクトの数と、オブジェクトが占有するメモリの変化を比較できます。 この情報を通じて、ヒープ内のオブジェクトの値を判断し、一定の操作 (特定の操作) 後のメモリの変化を判断することができ、これらの値を通じて異常なオブジェクトを見つけることができます。これらのオブジェクトの名前属性または関数によって、メモリ リーク調査の範囲が狭まる可能性があります。 [比較] ビューで 2 つのヒープ スナップショットを選択し、それらを比較します。 2 つのヒープ スナップショット間でどのオブジェクトが追加されたか、2 つのヒープ スナップショット間でどのオブジェクトが削減されたか、どのオブジェクトのサイズが変更されたかを確認できます。

比較

ビューでは、オブジェクト間の関係だけでなく、タイプ、サイズ、参照カウントなどのオブジェクトの詳細も表示できます。この情報により、どのオブジェクトがメモリ リークの原因となっているかを理解できます。

#包含ビュー

【体験談まとめ】Nodeのメモリリークのトラブルシューティング方法は?アイデアを共有する

オブジェクト間の到達可能なすべての参照関係を表示します。各オブジェクトは点として表され、その親オブジェクトに線で接続されます。こうすることで、オブジェクト間の階層関係を確認し、どのオブジェクトがメモリ リークの原因となっているかを把握できます。

#統計ビュー

【体験談まとめ】Nodeのメモリリークのトラブルシューティング方法は?アイデアを共有するこの図は非常に単純なので、詳細については説明しません

メモリ リークのシナリオ

  • グローバル変数: グローバル変数はリサイクルされません
  • キャッシュ: 次のようなメモリ集約型のサードパーティ ライブラリが使用されますlru-cache 保存しすぎるとメモリ不足になります。Nodejs サービスでは lru-cache の代わりに
  • redis
  • を使用することをお勧めします。ハンドル リーク: システム リソースは呼び出し後に解放されません
  • イベント モニタリング
  • 終了
  • 循環参照

概要

  • 問題の種類を初めて特定しやすくするために、サービスにはアクセス監視が必要です

  • メモリ リークがグローバルかローカルかを判断します

  • 二分法を使用して、グローバル メモリ リークのトラブルシューティングを迅速に行い、特定します。

  • ローカル メモリ リーク

    • メモリ リークが発生し、問題を迅速に特定します。 機能
    • ヒープ スナップショット データを少なくとも 3 回収集します。
    • 監視データ、ヒープ スナップショット データ、リーク発生時の新しい関数を組み合わせて、問題を特定します。メモリ リーク ポイント

メモリ リークの問題が発生しても恐れることはありません。メモリ リークの問題のトラブルシューティングでより多くの経験を積んでください。処理の経験が増えるほど、メモリ リークの問題は、すぐに見つけやすくなります。各解決策の後で、レビューと要約を実行し、もう一度振り返りますヒープ スナップショットデータは、関連するエクスペリエンスをより速く蓄積するのに役立ちます

その他

  • ストレス テスト ツール: wrk

ノード関連の知識については、nodejs チュートリアルを参照してください。

以上が【体験談まとめ】Nodeのメモリリークのトラブルシューティング方法は?アイデアを共有するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は掘金社区で複製されています。侵害がある場合は、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ヘンタイを無料で生成します。

ホットツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

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

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

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