序文
これは、プログラムの過失またはエラーによるリークが使用されなくなったメモリを解放するために失敗しないメモリを指します。メモリリークが消失物理メモリを参照していないが、従来のメモリの解放までの期間に生じたエラーを設計することにより、メモリ割り当ての一定期間の後、アプリケーションは、メモリの浪費をもたらす、メモリセグメントの制御を失います。ここではいくつかのメモリリークの一般的な原因をもたらすと言います。
0.5グローバル変数
それは変数宣言を扱うことができないのいずれかの方法のJavaScriptの自由:グローバルオブジェクトに新しい変数を作成するための参照で宣言されていない変数。ブラウザ環境では、グローバルオブジェクトは、ウィンドウです。
1つの 関数foo(){ 2 名= ' 末端は、前記' ; 3 } 4 // 実際に名前変数はウィンドウオブジェクトを取り付ける 。5 {関数foo() 。6 window.name = ' 末端は、前記' ; 7 } 8。 9。 // または 10 関数foo(){ 11。 この .nameのは= ' 末端が前記' ; 12である } 13である(FOO)// 実際には、これは、ウィンドウオブジェクトポイントであります
このような予想外の不注意グローバル変数が作成され、このようなエラーが発生しないようにするために、フロントはJavaScriptファイルを追加します 'use strict;'
。これは、より厳格なモードではJavaScriptを誤ってグローバルな解析を防止開きます。またはその明確に定義された変数に注意を払います!
1.循環参照
JSメモリ管理環境では、オブジェクトBへの参照オブジェクトと呼ばれるオブジェクトのオブジェクトBへのアクセスを持っている場合 参照カウントの戦略は、「オブジェクトがそれに他のオブジェクト参照を持っていない」オブジェクトへのオブジェクト参照あれば、そのオブジェクトが回収されるまで減少し、「オブジェクトはもはや必要とされている」ではありません。
1つの 関数func(){ 2 せOBJ1 = {}; 3 LET OBJ2 = {}; 4 5。 obj1.a = OBJ2; // OBJ1参照OBJ2 6。 obj2.a = OBJ1; // OBJ2参照OBJ1 。7 }
実行関数funcの終了後、戻り値は未定義である、機能、等全内部変数を回収しなければならないが、方法基準回数に応じて、参照OBJ1 OBJ2の数が0ではないので、それらは回収されません。循環参照の問題を解決するために、それは彼らが手動でnullに設定されているときにそれらを使用するのが最善ではありません。
ソリューション:obj1
と obj2
設定されています null
。
2.閉鎖
クロージャ:匿名関数は、変数親スコープにアクセスすることができます。
1つの VARの名前= (関数(){ 2 VARの名= ' JS-言う' ; 3 リターン機能(){ 4 にconsole.log(名前); 5 } 6 })()
不適切に使用した場合の閉鎖は、解決された後に発生することはできません、デッドロックに似ただけ回避することができ、循環参照(循環参照)、につながることができれば閉鎖は、ガベージコレクションでもある場合でも、現在の関数のコンテキストからのオブジェクト参照のライフサイクルになりますまだメモリリーク。
3.忘れられた遅延/タイマー
私たちの日常のニーズでは、それは多くの場合に試すこと setInterval/setTimeout
が、通常は使用後にクリーンアップするのを忘れ。
1 var someResource = getData(); 2 setInterval(function() { 3 var node = document.getElementById('Node'); 4 if(node) { 5 // 处理 node 和 someResource 6 node.innerHTML = JSON.stringify(someResource)); 7 } 8 }, 1000);
setInterval/setTimeout
this
点は、そのウィンドウオブジェクトであるので、内部変数の定義は、グローバルに取り付けられ、if
中で引用 someResource
クリアされない場合は、変数 setInterval/setTimeout
、その後someResource
も解放されない。共感は実際に setTimeout
同じ。だから我々はアウト実行するために覚えておく必要があります clearInterval/clearTimeout
。
4. DOMは、メモリリークを引き起こしました
- DOMへの明確な言及しません
1つの VAR refAと=のdocument.getElementById(' refAと' ); 2 document.body.removeChild(refAと); 3 // #refAがので可変refAと参照の、回収することができません。それは#refAへの参照を解放しますが、それでも#refAリサイクルすることができません。
ソリューション:refA = null
。
- DOMオブジェクトのプロパティは、オブジェクトへの参照を追加することです
VaRの MyObjectに= {}; document.getElementById(' myDiv ').myProp = MyObjectに。
解決策:ページの onunload
リリースイベント document.getElementById('myDiv').myProp = null;
。
DOMは、削除または明確な結合事象を空にしないこの状況は比較的一般的であるべきでなく、比較的容易に見過ごされるべきです。
- イベントをバインドするためにDOMオブジェクト
1 VARの BTN =のdocument.getElementById(" myBtnです" )。 2 btn.onclick = 関数(){ 3 のdocument.getElementById(" myDiv ").innerHTML = " 微信:JS-言います" 。 4 } 5 6 document.body.removeChild(BTN)。 7 BTN = NULL ;
イベントをクリアする必要があるので、ここで削除DOM、それでも結合事象を削除していないがメモリリークを引き起こす可能性があります。
1 VARの BTN =のdocument.getElementById(" myBtnです" )。 2 btn.onclick = 関数(){ 3 btn.onclick = NULL ; 4 のdocument.getElementById(" myDiv ").innerHTML = " 微信:JS-言います" 。 5 } 6 7 document.body.removeChild(BTN)。 8 BTN = NULL ;