JavaScriptメモリの漏洩
3479 ワード
1、閉パケットとは何か、および閉パケットに関連する役割ドメインチェーンはここでは言わない.
2、JavaScriptゴミ回収メカニズム
JavaScriptは手動でメモリを解放する必要はありません.自動ゴミ回収メカニズム(garbage collection)を使用します.オブジェクトが役に立たない場合、プログラムに変数がなくてこのオブジェクトを参照すると、メモリからこの変数が解放されます.
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は解放されません.
4、循環参照と閉パッケージ
したがって,閉包はループ参照を容易に作成でき,幸いにもJavaScriptはこのループ参照をうまく処理できる.
5、IEのメモリ漏れ
IEのメモリ漏れはいくつかありますが、ここでは詳細な説明があります(
http://msdn.microsoft.com/en-us/library/bb250448.aspx)ということで、園にも通訳がいました(
http://www.cnblogs.com/birdshome/archive/2006/05/28/ie_memoryleak.html ).
ここでは、最も一般的な状況であるため、ループリファレンスによるメモリ漏洩についてのみ議論します.
DOM要素またはActiveXオブジェクトと通常のJavaScriptオブジェクトとの間にループ参照が存在する場合、IEはこのような変数を解放する際に特別な困難があり、ループ参照を手動で切断することが望ましい.このバグはIE 7で修復されている(
http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html ).
“IE 6 suffered from memory leaks when a circular reference between several objects, among which at least one DOM node, was created. This problem has been solved in IE 7. ”
上記の例(4点目)のobjがJavaScript Functionオブジェクト(inner)ではなくActiveXオブジェクトまたはDom要素を参照している場合、IEに形成されたループ参照は解放されない.
Elemはclickイベントのリスニング関数を参照し、同様にこの関数はその役割ドメインチェーンを通じてelem要素も参照した.これにより、IEにおいて現在のページから離れても、これらのループ参照は解放されない.
6、解決方法
基本的な方法は、このループ参照を手動でクリアすることです.次の非常に簡単な例では、実際に適用するときにaddEvent()関数を自分で構築し、windowのunloadイベント上ですべてのイベントバインドをクリアすることができます.
原帖住所:
http://www.cnblogs.com/rainman/archive/2009/03/07/1405624.html
2、JavaScriptゴミ回収メカニズム
JavaScriptは手動でメモリを解放する必要はありません.自動ゴミ回収メカニズム(garbage collection)を使用します.オブジェクトが役に立たない場合、プログラムに変数がなくてこのオブジェクトを参照すると、メモリからこの変数が解放されます.
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 two = obj.pro.pro;
obj = null;
// {b:200} , {a:100} 。
4、循環参照と閉パッケージ
function outer(){
var obj = {};
function inner(){
// obj
}
obj.inner = inner;
}
これは、その隠蔽された循環参照である.outerを呼び出すと、objとinnerの2つのオブジェクトが内部に作成され、objのinnerプロパティはinnerを参照します.同様にinnerもobjを参照している.これはobjがinnerFunの閉鎖環境に残っているためであり、正確にはJavaScript特有の「役割ドメインチェーン」によるものである.したがって,閉包はループ参照を容易に作成でき,幸いにもJavaScriptはこのループ参照をうまく処理できる.
5、IEのメモリ漏れ
IEのメモリ漏れはいくつかありますが、ここでは詳細な説明があります(
http://msdn.microsoft.com/en-us/library/bb250448.aspx)ということで、園にも通訳がいました(
http://www.cnblogs.com/birdshome/archive/2006/05/28/ie_memoryleak.html ).
ここでは、最も一般的な状況であるため、ループリファレンスによるメモリ漏洩についてのみ議論します.
DOM要素またはActiveXオブジェクトと通常のJavaScriptオブジェクトとの間にループ参照が存在する場合、IEはこのような変数を解放する際に特別な困難があり、ループ参照を手動で切断することが望ましい.このバグはIE 7で修復されている(
http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html ).
“IE 6 suffered from memory leaks when a circular reference between several objects, among which at least one DOM node, was created. This problem has been solved in IE 7. ”
上記の例(4点目)のobjがJavaScript Functionオブジェクト(inner)ではなくActiveXオブジェクトまたはDom要素を参照している場合、IEに形成されたループ参照は解放されない.
function init(){
var elem = document.getElementByid( 'id' );
elem.onclick = function(){
alert('rain-man');
// elem
};
}
Elemはclickイベントのリスニング関数を参照し、同様にこの関数はその役割ドメインチェーンを通じてelem要素も参照した.これにより、IEにおいて現在のページから離れても、これらのループ参照は解放されない.
6、解決方法
基本的な方法は、このループ参照を手動でクリアすることです.次の非常に簡単な例では、実際に適用するときにaddEvent()関数を自分で構築し、windowのunloadイベント上ですべてのイベントバインドをクリアすることができます.
function outer(){
var one = document.getElementById( 'one' );
one.onclick = function(){};
}
window.onunload = function(){
var one = document.getElementById( 'one' );
one.onclick = null;
};
原帖住所:
http://www.cnblogs.com/rainman/archive/2009/03/07/1405624.html