21

私のサイトは非常に標準的な ecom サイトです。JS を使用したスタンドアロン アプリなどではなく、標準的なものに JS を使用し、いくつかのことを行うためにいくつかの jquery プラグインを使用するサイトです。

サイトで JS メモリ評価を実行しようとしています。Chrome タスク マネージャーとヒープ スナップショットを見て、これを行いました。

最初の読み込み時のサイトは、タスク マネージャーで 35MB (つまり 35,000K) から 40MB の間にあります。他の Web サイトの複数のタブを同時に開いている場合、これはどのタブよりも大きくなります。ページを更新すると、55 ~ 60 にジャンプし、別の更新では 65 ~ 70 MB にジャンプします。

ワークフローの通常のページでは、45 ~ 65 の間で変動します (実行内容によっては 75 になることもあります)。クリックしてページからページへとワークフローを実行すると、メモリが 85 ~ 100 に跳ね上がり、サイトを進むにつれて増加します。

チェックのようないくつかのことを試みました:

  • 検出されたノード
  • ヒープのスナップショットとデルタの確認
  • オブジェクトのサイズをチェックする amix の MemoryLeakChecker

循環参照や閉鎖の問題を探すには、さらに深く掘り下げる必要があります。

ヒープ スナップショットはあまり明らかにしません。トップ リストのほとんどは (配列)、(文字列)、(システム) です。スナップショットは、4.8MB、5.1MB、5.8MB、6.8MB の間にあり、増加します。

その結果、いくつかの質問があります。

  • How do I understand the different metrics between snapshot memory and task manager memory
  • Are there any good tutorials (apart from the ones on the Google Developers site)?
  • How much memory is considered acceptable? Given in the task manager my site is always the highest?
  • Do I have a memory leak? Apart from the steps I've described above (which I haven't found anything concrete from) is there any other ways I can find leaks?
  • Can you suggest any tools apart from the Chrome Dev Tools (a lot of the tools mentioned on Google for Firefox are not compatible with the latest version, eg: Leak Monitor for FF)

補足として、私の機能のほとんどは控えめな操作であり、200 ミリ秒を超えません (CPU プロファイルに基づく)。私が目指すべき良いベンチマークは何ですか?200msは高いですか?

4

2 に答える 2

38

あなたが説明しているのはメモリリークではありません.Chromeが知っているガベージであり、Chromeがそれを行う時が来たと判断するたびに削除されます. これを説明するために、あなたが説明したシナリオを詳しく見てみましょう。

メモリを「リーク」させる

  • まず、新しいシークレット ウィンドウを開き (ブラウザーの拡張機能が結果に影響を与えていないことを確認するため)、google.com に移動します。
  • 次に、タスク マネージャーを開き、[JavaScript メモリ] 列を有効にします (タスク マネージャー ウィンドウを右クリックします)。「リーク」するメモリが実際に JavaScript によって割り当てられていることを確認するには、この列が必要です。最終的には次のようになります。

最初のロード

  • さて、あなたが提案したように、ページを数回リロードして、タブのメモリが上がるのを観察する必要があります。

5 回以上のリロード後

これまでのところ、とても良いです-すべてがあなたが説明したとおりに機能します.

一瞬待って...

ただし、カーソルを 30 分間非アクティブにするか、別のタブに移動すると、「Tab:google」でメモリ使用量が大幅に低下することがわかります。何故ですか?そこで何が起こった?「漏洩した」記憶をクリーンアップしたのは誰ですか?

メモリ使用量の低下

それを調べるために、これまでに行ったことを繰り返して、'Tab:google' が再び大量のメモリを使用するようにします。次に、Chrome 開発者ツールを開き、[タイムライン] タブで記録を開始します。その後、数秒間タブを変更し、メモリが低下したら「タイムライン」の「記録」を停止します。あなたはこれで終わるはずです:

ここに画像の説明を入力

レコーディングの最後の数秒で、謎の「GC イベント」が現れました。記憶が解放されたのとちょうど同じ時間。一致?いいえ。

GC イベント

GC はガベージ コレクターの略です。これは、「ガベージ、またはプログラムで使用されなくなったオブジェクトによって占有されているメモリを再利用しようとする」メカニズムです。したがって、タブのメモリはガベージによって汚染されており、GC はこれらのガベージを完全に取り除くことができたことがわかりました ([タイムライン] タブの下部にあるボタンを使用してガベージ コレクションを強制することもできます)。では、なぜそうしないことにしたのですか?ページの操作を停止したり、タブを変更したりするのを待っていたのはなぜですか?

怠惰なガベージ コレクター

手短に言えば、ガベージ コレクションでは、作業を行う前にすべてのスクリプトの実行を「凍結」する必要があります。また、実行にはかなりの量の CPU 時間がかかる場合があります。これにより、ラグ、途切れ途切れのアニメーション、無応答のコントロールなどが発生する可能性があります。そのため、Chromeはガベージ コレクションを呼び出す適切なタイミングを待ちます。そして、それを行うのに最適な瞬間は、ユーザーが見ていないときです。

さらに、'GC イベント' はシリーズで行われることに注意してください。間に短い休憩を入れて、常にいくつかのイベントがあります。これらの中断は、「通常の」JavaScript を実行してガベージ コレクションを目立たなくするためのものです。

ライブオブジェクト

この投稿の上部 2 つのスクリーンショットにある [JavaScript メモリ] タブをもう一度見てください。この列には 2 つの数値が含まれていることがわかります。最初の 1 つは「JavaScript VM ヒープ用に予約された」メモリであり、もう 1 つは「ライブ (到達可能な) オブジェクトが構成するメモリの量」( source ) です。アプリケーションのベンチマークを行うときは、2 番目の値だけを気にする必要があります。残りはすべて GC によって処理されます。

漏れの例

実際の JavaScript リークが発生する可能性があります。Web チャット アプリケーションで。時間の経過とともに、常に最新の 10 件のメッセージのみを表示しながら、より多くの「ライブ」メモリを使用する場合はリークについて話すことができます。このようなリークは、最終的にタブ (またはブラウザー) をクラッシュさせます。

結論

ページで実行されているスクリプトの場合、ページを再読み込みする (または別の場所に移動する) ことは、ANSI C アプリの実行中にコンピューターを再起動することと同じです。その後、スクリプトによって割り当てられたすべてのメモリが消去されたと考える必要があります。実際には、ページをリロードした直後にこれが発生しない可能性がある唯一の理由は、ブラウザーがクリーンアップの適切な瞬間を待っているためです。そして、Web 開発者として、それについて心配する必要はありません。

于 2013-01-07T01:04:17.540 に答える
1

それでもページがリークしていると思われる場合は、この質問の回答を使用して、リークされたオブジェクトを追跡できます。

于 2013-01-11T08:56:45.177 に答える