0

アプリケーションでメモリ リークを検出するための環境をセットアップしようとしています。

アプリのセットアップ: Angular + Electron
アプリの使用をシミュレート: Mocha + Spectron + Webdriverio

新しくセットアップしたアプリで実行し、各プロセスのメモリ使用量を定期的に収集するさまざまなユーザー シナリオのテストがあります。

アプリがアイドル状態の場合、メモリ使用量は予想どおりです。しかし、他のテスト ケースで問題が発生しました。mocha を使用してテストを実行すると、予期しない未知の構造がメモリに表示されるようです。その結果、メモリ リークが発生します。


以下にスクリーンショットを添付しました (開発ツールの [メモリ] タブ)。これが私の混乱を最もよく表しています。

  • スナップショット 1: アプリのセットアップ後に撮影 ( 81.8 MB )
  • スナップショット 2: テストのグループが完了し (通常の使用で ~ 10 分)、アプリが開始状態に戻った後に取得 ( 109 MB )
  • スナップショット 3: (「ガベージを収集」ボタンを使用して) GC を強制した後に取得 ( 108 MB )

スナップショット 1 と 2 を比較すると、メモリの大部分 (~19 MB) が文字列内にあることがわかります。

リテイナーを調べると、これらの文字列が (グローバル ハンドラー)>(GC ルート) にリンクされていることがわかります。文字列の 1 つを選択$0してコンソールで実行すると、すべての文字列に対して同じ出力が得られます: <body>...</body>. 要素にカーソルを合わせると、アプリの本体にリンクされます (すべての文字列に対して)。

「文字列構造の拡張」は、一部のモジュールが複数回ロードされ、その参照が決して破棄されないことが原因であると感じます (私の推測では、Module()inを介してロードされinternal/modules/cjs/loader.js:136ます)。

文字列構造の拡張

「割り当てタイムライン」でメモリを調べると、「ヒープ スナップショット > 比較」の下に新しい「大きな文字列オブジェクト」が表示される同じアクションで、解放されていないメモリの下にこの「大きな文字列オブジェクト」が見つかりません。

テスト シナリオを手動でシミュレートするか、コンソールで関数を介してクリックをシミュレートすると、メモリ リークは発生しません。

そのすべてが私に考えさせます、私は何か間違ったことをしている、または使用しています(モカに関して)。


私の質問:

  1. mocha はこの種の設定には適していません (つまり、アプリが閉じられるまでいくつかの参照を保持します)?
  2. (グローバル ハンドラー) > (GC ルート) によってのみ構造が保持されている場合、いつ解放されますか? 私はここで、それらはあなたが心配する必要があるものではないことを読みましたが、私の場合、それらは:/
  3. 複数の文字列 (複数の参照) があり、 を介して呼び出されたときに$0、すべてが同じ DOM 要素 ( <body>) を参照するのはなぜですか?
  4. この文字列オブジェクトが「割り当てタイムライン」に表示されないのはなぜですか?
  5. このタイプのメモリリークの原因は何ですか?
4

1 に答える 1