1.閉鎖とは何ですか、閉鎖に伴うスコープチェーンについてはここでは説明しません。
2。JavaScriptガベージコレクションメカニズム
JavaScriptはメモリを手動で解放する必要はありません。自動ガベージコレクションメカニズムを使用します。オブジェクトが役に立たない場合、つまり、プログラムの変数がオブジェクトを参照していない場合、変数はメモリから解放されます。
コードコピーは次のとおりです。
var s = [1、2,3];
var s = null;
//このようにして、元の配列[1、2、3]がリリースされます。
3.リサイクル引用
3つのオブジェクトA、B、c
Aàbàc:Aの特定の属性はBを参照し、CはBの属性によっても参照されます。 Aがクリアされた場合、BとCもリリースされます。
Aàbàcàb:ここには、Cの特定の属性がBオブジェクトを参照して追加されます。これがAをクリアする場合、BとCの間に円形の参照が生成されるため、BとCはリリースされません。
コードコピーは次のとおりです。
var a = {};
a.pro = {a:100};
a.pro.pro = {b:100};
a = null;
//この場合、{a:100}と{b:100}も同時にリリースされます。
var obj = {};
obj.pro = {a:100};
obj.pro.pro = {b:200};
var 2 = obj.pro.pro;
obj = null;
//この場合、{b:200}はリリースされませんが、{a:100}はリリースされます。
4.リサイクル参照と閉鎖
コードコピーは次のとおりです。
function outer(){
var obj = {};
関数内(){
// OBJオブジェクトはここで参照されています
}
obj.inner = inner;
}
これは一種の隠された円形の参照です。外側が1回呼ばれると、2つのオブジェクトがOBJと内側に作成されます。 OBJの内部財産は内なるものを指します。 OBJはまだinnerfunの閉鎖環境にあるため、同様の内側もOBJを指します。正確には、これはJavaScriptのユニークな「スコープチェーン」によるものです。
したがって、閉鎖は円形の参照を作成するのが非常に簡単であり、幸いなことにJavaScriptはそのような円形の参照を非常にうまく処理できます。
5。IEのメモリリーク
IEにはいくつかのメモリリークがあり、ここには詳細な説明があります(http://msdn.microsoft.com/en-us/library/bb250448.aspx)。
ここでは、これらのうちの1つのみ、つまり、これが最も一般的な状況であるため、循環参照によって引き起こされるメモリリークです。
DOM要素またはActiveXオブジェクトと通常のJavaScriptオブジェクトの間にループ参照がある場合、IEはそのような変数を解放するのに特別な困難を抱えています。ループリファレンスを手動でカットするのが最善です。このバグは、IE 7(http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html)で修正されています。
「IE 6は、少なくとも1つのDOMノードが作成されたいくつかのオブジェクト間の円形の参照が作成されたときに、メモリリークに苦しみました。この問題はIE 7で解決されました。」
上記の例(ポイント4)のOBJは、JavaScript関数オブジェクト(内側)ではなく、ActiveXオブジェクトまたはDOM要素ではなく、IEで形成された円形の参照をリリースできません。
コードコピーは次のとおりです。
function init(){
var elem = document.getElementById( 'id');
elem.onclick = function(){
アラート( 'rain-man');
// ELEM要素はここで参照されています
};
}
Elemは、Click Eventのリスニング機能を指し、この機能はスコープチェーンを介してElem要素を参照します。これにより、現在のページをIEで残しても、これらの円形の参照はリリースされません。
6。解決策
基本的な方法は、この円形の参照を手動でクリアすることです。以下は非常に簡単な例です。使用すると、addevent()機能を自分で構築し、ウィンドウのアンロードイベントですべてのイベントバインディングをクリアできます。
コードコピーは次のとおりです。
function outer(){
var one = document.getElementById( 'One');
one.onclick = function(){};
}
window.onunload = function(){
var one = document.getElementById( 'One');
one.onclick = null;
};
その他の方法(:ダグラス・クロックフォード)
コードコピーは次のとおりです。
/**
*特定の要素ノードとすべての子孫要素を繰り返します
*
* @paramElemノードクリアする要素ノードをノード
* @param関数処理のためのFUNC関数
*
*/
function walkthedom(node、func){
FUNC(ノード);
node = node.firstchild;
while(node){
Walkthedom(ノード、FUNC);
node = node.nextsibling;
}
}
/**
*メモリの漏れを防ぐために、DOMノードからすべての参照をクリアする
*
* @paramElemノードクリアする要素ノードをノード
*
*/
関数purgeeventhandlers(node){
walkthedom(node、function(e){
for(var n in e){
if(typeof e [n] ===
'関数') {
e [n] = null;
}
}
});
上記は、JavaScriptメモリリークの関連コンテンツとソリューションです。それを必要とする友達はそれを参照できます。