メモリリークのJS

今日では、あなたとJSの下で知識メモリリークを共有します。

メモリリークの1つのJS

はじめに
、このようなスクリプト言語のJavaScriptを扱う際には、各オブジェクトの、クラス、文字列、数値および方法が割り当てられる必要があることを忘れやすく、予約メモリです。言語とランタイムのガベージコレクタは、メモリの割り当てと解放の詳細を隠します。
多くの機能は、メモリ管理に関係なく実現するが、それはプログラムの中で大きな問題を引き起こす可能性が無視することができます。オブジェクトアップ不適切なクリーニングがはるかに長い予想以上に存在してもよいです。これらのオブジェクトは、イベントに応答し続けるとリソースを消費します。
彼らは大幅にコンピュータの速度に影響する仮想ディスクドライブからメモリページを割り当てるために、ブラウザを強制することができます(極端な場合には、クラッシュにブラウザを引き起こす可能性があります)。

メモリリーク手段オブジェクトは、もはや必要性を持っていないか、後でそれはあなたの中にまだそこだと。近年では、多くのブラウザはJavaScriptの再利用メモリからページの読み込みプロセスを改善する能力を持っています。ただし、すべてのブラウザが同じ動作モードを持っていません。

FirefoxとInternet Explorerの古いバージョンのメモリリークを存在していたし、ブラウザを閉じるまでメモリリークが続きました。

過去にわたり、もはやに近代的なブラウザでは、多くのクラシックモードのメモリリークにつながったメモリリークが発生します。しかし、異なる傾向が今メモリリークに影響を与えています。多くは、単一のページを更新してハードページが存在しない場合に実行されるWebアプリケーション用に設計されています。単一のページとして、別の状態からアプリケーションの状態は、もはや必要ではないか、関連するメモリを保持することは容易です。

この記事では、オブジェクト、オブジェクトが解放されているかどうか、そしてどのように潜在的な漏れの挙動を評価するための方法についてのガベージコレクタの基本的なライフサイクルを学びます。また、ヒーププロファイラGoogle Chromeはメモリの問題を診断することで使用する方法を学びます。いくつかの例には、クロージャを解決する方法を示し、およびコンソールログサイクルは、メモリリークを引き起こしました。

オブジェクトのライフサイクル
メモリリークを防ぐために方法を学ぶために、オブジェクトの基本的なライフサイクルを理解する必要があります。あなたがオブジェクトを作成すると、JavaScriptは自動的にオブジェクトのための適切なメモリを割り当てます。この瞬間から、ガベージコレクタは、それがまだ有効なオブジェクトであるかどうかを確認するために、オブジェクトを評価していきます。

ガベージコレクタは、定期的にオブジェクトをスキャンし、各オブジェクトの他のオブジェクトへの参照の数を算出します。オブジェクトの参照番号が0(オブジェクトを通じて他のオブジェクト参照)されていない、またはオブジェクトへの参照のみが円形である場合、オブジェクトのメモリを回収することができます。
図1は、ガベージコレクタのメモリの一例を示しています。
再利用メモリへ図1.ガベージコレクション
ここに画像を挿入説明
システムの実用化が参考になるが、この機能は、ツールを提供して見ることが制限されています。メモリは、ブラウザのメモリ割り当てを確認するためにシステムツールを使用する方法ですどのくらいのあなたのJavaScriptアプリケーションが消費を知っています。そこにあなたの現在の使用のために利用できるいくつかのツールがあり、メモリ使用量の傾向は、時間の経過とともに変化の過程を描いています。

あなたは、Mac OSXにはXCodeをインストールした場合たとえば、あなたがリアルタイム分析のために、ブラウザに添付インスツルメンツアプリケーションとそのアクティビティモニタツールを起動することができます。Windows®では、あなたは、タスクマネージャを使用することができます。あなたがアプリケーションを使用する過程で、私たちは、曲線は着実に上昇し、時間に対するメモリ使用量を発見した場合は、メモリリークがあると知っています。

観測ブラウザのメモリフットプリントJavaScriptアプリケーションの実際のメモリ使用量の最も生々しいのみ表示。ブラウザのデータが一致しないアプリケーションに実メモリの使用状況データを保証することはできません、リークをどのオブジェクトを教えてくれません。

また、DOM要素(またはバックアップ・アプリケーション・レベルのオブジェクト)、ブラウザを達成するための問題のいくつかの放出に起因するページに対応する要素を破壊しなくてもよいです。これは特に、真のvideoタグ、あなたはより洗練されたインフラストラクチャを実装する必要がvideoタグです。

これを繰り返し、クライアント側のJavaScriptライブラリでメモリ割り当てに追跡を追加しようとしています。残念ながら、すべての試みは、特に信頼性がありません。

たとえば、人気のstats.jsパッケージの不正確さをサポートすることができません。一般的には、維持しようとか、それがアプリケーションにオーバーヘッド紹介し、確実に終了することができないため、クライアントから、この情報を特定の問題があると判断。

理想的なソリューションは、ブラウザ、あなたはメモリ使用量を監視するのに役立ちオブジェクト漏れを特定し、予約済みとして特定のオブジェクトがまだマークされている理由を判断するためのツールのセットで、ブラウザのベンダーです。

現在のところ、Google Chromeでのみ(提供ヒーププロファイル)は、その開発ツールのようなメモリ管理ツールを実装しています。私は、実行時のメモリを処理する方法この記事でHeapProfilerテストとデモはJavaScriptを使用しています。

分析ヒープのスナップショットは、
メモリリークを作成する前に、簡単な対話メモリを収集するための適切な時間を確認してください。まず、リスト1に示すように、2つのボタンが含まれている簡単なHTMLページを作成します。
リスト1. index.htmlには、
ここに画像を挿入説明
最も一般的な開発手法と異なるブラウザのイベントバインディングを管理するための単純な構文、および厳格な遵守を確保するために、jQueryのがあります。リーカークラスと主要なJavaScriptのメソッドのためのスクリプトタグを追加します。開発環境では、単一のファイルにJavaScriptファイルをマージします通常より良いアプローチです。この例の目的のために、簡単に別のファイル内のロジック。

あなただけ表示するように特定のクラスのヒーププロファイラのインスタンスをフィルタリングすることができます。この機能を利用するには、新しいクラスの振る舞いにオブジェクトをリークするパッケージを作成し、リスト2に示すように、このクラスは、非常に簡単なヒーププロファイラで見つけることです。
2.assets /スクリプト/ leaker.jsリスト
ここに画像を挿入説明
オブジェクトを初期化し、変数のグローバルネームスペースに割り当てリーカーにスタート]ボタンを結合します。ボタンを破壊もリーカーオブジェクトをきれいにし、リスト3に示したガベージコレクションのためのそれの準備ができているべきである方法にバインドする必要があります。

3.assets /スクリプト/ main.jsリスト
ここに画像を挿入説明
さて、あなたはメモリにそれを見て、それを解放するためにオブジェクトを作成する準備ができました。

Chromeでインデックスページをロードします。あなたがGoogleからの直接のjQueryをロードされるので、あなたは、サンプルを実行するにはインターネット接続が必要です。

[表示]メニューを開き、サブメニューを開発選ぶことにより、オープン開発ツール。開発者ツールのコマンドを選択します。

プロファイル]タブに移動し、図2に示すように、ヒープのスナップショットを取得します。
図2.プロファイル]タブ、
ここに画像を挿入説明
注意が開始]を選択し、Webに戻りました。

別のヒープのスナップショットを取得します。

最初のスナップショットのフィルタリング、インスタンスリーカークラスを見つけ、私はすべての例を見つけることができませんでした。2番目のスナップショットへの切り替えは、図に示すように、例を見つけることができるはずです。
図3.スナップショットインスタンスのここに画像を挿入説明
注意は、破棄選択したWebに戻りました。

第三ヒープのスナップショットを取得します。

第3のフィルタのスナップショット、インスタンスリーカークラスを見つけ、私はすべての例を見つけることができませんでした。
第三のスナップショットがロードされると、分析も比較要約をモードから切り替え、第3及び第二のスナップショットを比較することができます。あなたは、オフセット値-1(インスタンスリーカーオブジェクトをリリース2つのスナップショット間)が表示されます。

万歳!効果的なガベージコレクション。今それを破るための時間です。

メモリリーク:クロージャ
浪費を防止する簡単な方法を回収し、オブジェクトがオブジェクト・セットの間隔またはタイムアウトコールバックへの参照です。リスト4に示すように、再生可能leaker.jsクラスの実用化を参照してください。
4.assets /スクリプト/ leaker.jsリストここに画像を挿入説明
セクションでは、あなたが第三のスナップショットが表示されるはずです今、時に繰り返し手順1-9、リーカーオブジェクトは永続的である、とのギャップは永遠に実行し続けます。だから何が起こったのか?任意のローカル変数の閉鎖に関連して存在閉鎖が確保されることはありません限り、閉じられたパッケージに保持されます。

たsetIntervalコールバックメソッドがときにアクセス範囲リーカーインスタンス実行されていることを確認するために、この変数自己ローカル変数に代入する必要があり、この変数は、閉鎖からのトリガonIntervalために使用されます。onIntervalがトリガされると、それは(それ自身を含む)任意のインスタンス変数リーカーオブジェクトにアクセスすることができます。

しかし、限り、イベントリスナーがあるとして、リーカーオブジェクトは、ごみは収集されません。

リスト5に示すように、この問題を解決するには、オブジェクトのメソッドを破壊するために追加のトリガ、リーカーが保存された参照オブジェクト空にする前に、この方法では、ボタンのクリックハンドラを破壊更新することです。
リスト5.assets /スクリプト/ main.jsは、
ここに画像を挿入説明
オブジェクトを破壊し、オブジェクトの所有権の
アプローチは、責任オブジェクトがガベージの対象となるようにする標準的な方法を作成するための素晴らしい方法です。主な目的は、デューティ操作をクリーニングに焦点が完了し、そのオブジェクトの次のような結果を持っていることの機能を破壊します:

その参照カウントが(例えば、イベントリスナーの問題とコールバック、および任意のサービスからの登録解除を取り除く)ゼロに低下停止します。

そのような間隔またはアニメーションなどのCPUサイクルの不必要な使用。

destroyメソッドは、多くの場合、オブジェクトをクリーンアップするために必要なステップですが、ほとんどの場合、それは十分ではありません。理論的には、関連するインスタンスを破壊した後、他のオブジェクト参照の保存方法が破棄されたオブジェクトが自分で呼び出すことができます。

この状況は、予期しない結果を生じる可能性があるため、それほど不可欠であり、オブジェクトは役に立たない程度である場合にのみ、メソッドが呼び出され破壊します。

一般的には、破壊する最善の方法は、そのライフサイクルの間に明確な責任を所有者にオブジェクトを使用することです。この状況は、そのようなビューMVCフレームワーク又はコントローラ、又は図のキャンバスシーンレンダリングシステムとして、層システムでしばしば存在します。

メモリリーク2:コンソールログ
少ないメモリでそれを維持するために明白な方法は、コンソールにそれを記録することです。6つの更新リーカークラスリスト、それがこの方法の一例を示しています。
リスト6.assets /スクリプト/ leaker.jsは、ここに画像を挿入説明
コンソールの影響を実証するために、次の手順を取ることができます。

  • インデックスページにログオンします。
  • [スタート]をクリックします。
  • ゴーコンソールへと漏れたオブジェクトが追跡されていることを確認してください。
  • 破壊をクリックします。
  • コンソールと種類漏れに戻るには、グローバル変数の現在の内容を記録します。この値は、現時点では空である必要があります。
  • 別のヒープのスナップショット、そして濾過リーカーオブジェクトを取得します。
  • あなたはリーカーオブジェクトを残す必要があります。コンソールに戻って、それを削除します。
  • 別のヒーププロファイルを作成します。
  • コンソールをクリーンアップした後、リーカーを保持すべき設定ファイルがクリアされました。

全体的なメモリ構成ファイルのコンソールログへの影響は、多くの開発者にとって非常に重要な問題になる可能性がどれを考えます。エラーオブジェクトはメモリに保持大量のデータを記録することができます。これもに適用されることに注意してください:

  • 場合はJavaScriptでユーザーの種類、インタラクティブなセッション中に記録され、コンソール内のオブジェクト。
  • CONSOLE.LOG及び方法console.dirオブジェクトによって記録されます。

メモリリーク3:サイクル
図に示すように、2つのオブジェクト参照互いと互いに保持するためには、サイクルを生成します。
図は、基準サイクル作成4.
ここに画像を挿入説明
図7に示す簡単なコード例をリストします。
7.assets /スクリプトをリスト/ leaker.jsはここに画像を挿入説明
リスト8に示すように、ルートオブジェクトは、修正することができ、インスタンス化。
8.assets /スクリプト/ main.jsをリストここに画像を挿入説明
オブジェクトの破壊後、ヒープの分析を作成して実行する場合は、あなたが破棄ボタンを選択すると、この循環参照、およびリリースのメモリを検出するために、ガベージコレクタが表示されるはずです。

しかし、オブジェクトのサブオブジェクトを保持する第三の導入の場合、ループは、メモリリークが発生します。リスト9に示すように、例えば、レジストリオブジェクトを作成します。
9.assets /スクリプトのリスト/ registry.js ここに画像を挿入説明
レジストリクラスは他のオブジェクトがそれを登録して、レジストリからそれ自体が単純な例のオブジェクトを削除できるようにすることです。この特定のクラスやレジストリ関係のないが、しかしこれは、コモンモードでのイベントスケジューラおよび通知システムです。

リスト10に示すように、index.htmlのページへのクラスは、leaker.jsの前に置きました。
10. index.htmlをリスト
ここに画像を挿入説明
更新リーカーオブジェクトを、(未実現イベントのいくつかについて通知するために使用されてもよい)オブジェクト自体を登録するためにレジストリへのオブジェクト。

これは、代替パスのルートノードを保持するリーカーからサブオブジェクトを作成しますが、リスト11に示すようにので、サイクルの、親オブジェクトはまた、保持されています。
11.資産/スクリプト/ leaker.jsリストここに画像を挿入説明
最後に、main.jsには、レジストリを設定するために更新され、レジストリは、リスト12に示すように、リーカーに渡された親オブジェクトへの参照です。
12.assets /スクリプト/ main.jsリストここに画像を挿入説明
今を、時に実行スタック分析、次の2つの新しいインスタンスリーカーオブジェクトを作成し、保持されます、[スタート]ボタンを選択するたびに表示されるはずです。図5に示すオブジェクト参照のフロー図。
図5によりにより引き起こされるメモリリークを参照保持する
ここに画像を挿入説明
面を、それが不自然例と同様であるが、それは実際には非常に一般的です。イベントリスナーがより古典的オブジェクト指向フレームワークは、多くの場合、同様のパターン図5に従います。このパターンの種類との問題点は、クロージャと関連するコンソールログにつながる可能性があります。

そこにこの問題を解決する方法はいくつかありますが、この場合には、最も簡単な方法は、ときにそれを破壊するその子オブジェクトを破壊するリーカークラスを更新することである。が、この例では、方法(リスト13)を破壊更新することで十分です。
13.assets /スクリプト/ leaker.jsをリストここに画像を挿入説明時にはまだオブジェクト、他のオブジェクトのオブジェクトの一つのライフサイクル管理との間に密接な関係の2つのサイクルがあるでしょう足りません。彼らはサイクルが中止されて破壊されたときに、この場合には、これら2つのオブジェクト間のオブジェクトの関係は、責任を負わなければなりません。

結論
JavaScriptがゴミであっても、まだ不要なオブジェクトがメモリ内に残る多くの方法があるでしょう。現在、ほとんどのブラウザでは、メモリクリーニング機能を改善しているが、あなたのアプリケーションのメモリヒープツールの評価はまだ(Google Chromeのを除く)限定されています。

簡単なテストケースから始まることで、潜在的な漏れの挙動を評価し、漏れがあるかどうかを判断することは容易です。

テストされていない、正確にメモリ使用量を測定することは不可能です。オブジェクトグラフの循環参照領域の大半を占めるように簡単です。Chromeのヒーププロファイラは、定期的に、それを使用するメモリの問題を診断するための貴重なツールであるにも発展途上良い選択です。

予測対象グラフの特定のリソースを解放して、検証する際に設定した特定のは、予想されます。あなたは望ましくない結果を見るたびに、慎重に検討します。

あなたがオブジェクトを作成すると、アプリケーションはるかに簡単に移植清算段階よりも後にあるオブジェクトのクリーンアップを計画します。多くの場合、スケジュールイベントリスナーを削除し、作成した区間を停止します。あなたのアプリケーションのメモリ使用量を認識している場合は、より信頼性が高く実行するアプリケーションになります。
http://www.ibm.com/developerworks/cn/web/wa-jsmemory/

メモリリークのJSについて、あなたはどのくらいを学びますか?コメントは、コメント領域に歓迎されています!

公開された180元の記事 ウォン称賛13 ビュー7174

おすすめ

転載: blog.csdn.net/weixin_45794138/article/details/104859633