JScriptのメモリ漏れ
2261 ワード
システムが適切にメモリの割り当てを管理していない場合、メモリリークと呼ばれ、メモリリークはバグです.この問題は性能低下と運転エラーを引き起こします.
マイクロソフトのInternet Explorerは多くの漏洩問題があります.JScriptとの相互作用が最も深刻です.DomオブジェクトがJavaScriptオブジェクトへの参照を含む場合(例えば、イベントのハンドル関数event handling function)、そしてそのJavaScriptオブジェクトがそのDomオブジェクトへの参照を含むと、環状構造が形成される.この本質は問題ではない.この時、DOMオブジェクトとイベントのハンドルを他の引用していない場合、ゴミ回収器(自動メモリリソースマネージャ)はメモリを回収して、それらのスペースを再度割り当てることができます.ゴミの回収は、その環状構造を理解し、迷惑をかけることはありません.残念なことに、IEのDOM構造はJScriptによって管理されておらず、自分のメモリマネージャがあります.そのメモリマネージャはその環状構造を理解していません.これは環状構造が発生すると、メモリの回収がもう発生しなくなります.メモリが回収されなくなったことは漏れと呼ばれ、時間が経つにつれてメモリが無くなります.メモリの容量がいっぱいになりました.ブラウザが死んでしまいました.
上記について論証することができます.最初のプログラムでは、1列テストを行います.1,000個のDOMオブジェクト(spanオブジェクト)を追加します.同時に、最近の10個のオブジェクトを削除します.それを実行すると、Windowsのタスクマネージャの性能ページでPF(ページファイル)の使用状況を観察し、正常であることが分かります.PFの変更使用率はメモリ割り当て効率を示すことができる.
続いて、第二のプログラムを実行して、キューテスト2はもうテスト1と同じ結果になりません.唯一の変動は、各オブジェクトにclick_handlerを追加しました.MozilaとOperaでは、PFの使用は安定していますが、IEではPFが着実に増加し、メモリ漏れは毎秒数メガバイトの増加をもたらします.通常この漏れは注意に値するものではない.しかし、Ajax技術が流行し、1ページの滞在時間が長くなり、ページがより多く変わり、失敗が一般的になりました.
IEはその仕事をうまく行って環状構造を回収できません.この任務は私達の体に落ちました.もし私達がリング機構を明確に壊したら、IEはメモリを回収することができます.マイクロソフトによると、クローズド(closures)は内部エラーの原因となります.これはもちろん重大な誤りですが、マイクロソフトはプログラマーたちに悪い提案をしてマイクロソフトのバグに対処します.これはDOM側から問題が解決しやすい面を閉じて、事実上解決できないJScript側に任せました.
私たちはもう一つのオブジェクトを使用しないと、そのすべてのevent handersをクリアして循環参照を破壊しなければなりません.すべての私たちがしなければならないのは、各event handler属性をnull値に設定することです.これは明確に行うことができますし、または汎用的な浄化関数を書くことができます.
浄化プログラムはDOMオブジェクトをパラメータとして参照します.このサイクル要素のすべての属性は、関数が発見されたら、nullに設定されます.これは循環参照を破壊し、メモリの再生を許可します.これは元素の派生要素でもあります.これは循環参照をよくクリアします.浄化関数はMozillaとOperaに無害で、IEに適用されます.浄化プログラムは、任意の要素を除去する時に呼び出しられ、removeChildメソッドとinnerHTML属性を設定する前に使用します.
説明:メモリ漏れの問題はIE 9まで解決されますので、プログラミングには特に注意してください.
Duglas Crockford原文:JScript Memory Leaks翻訳:blogspot
マイクロソフトのInternet Explorerは多くの漏洩問題があります.JScriptとの相互作用が最も深刻です.DomオブジェクトがJavaScriptオブジェクトへの参照を含む場合(例えば、イベントのハンドル関数event handling function)、そしてそのJavaScriptオブジェクトがそのDomオブジェクトへの参照を含むと、環状構造が形成される.この本質は問題ではない.この時、DOMオブジェクトとイベントのハンドルを他の引用していない場合、ゴミ回収器(自動メモリリソースマネージャ)はメモリを回収して、それらのスペースを再度割り当てることができます.ゴミの回収は、その環状構造を理解し、迷惑をかけることはありません.残念なことに、IEのDOM構造はJScriptによって管理されておらず、自分のメモリマネージャがあります.そのメモリマネージャはその環状構造を理解していません.これは環状構造が発生すると、メモリの回収がもう発生しなくなります.メモリが回収されなくなったことは漏れと呼ばれ、時間が経つにつれてメモリが無くなります.メモリの容量がいっぱいになりました.ブラウザが死んでしまいました.
上記について論証することができます.最初のプログラムでは、1列テストを行います.1,000個のDOMオブジェクト(spanオブジェクト)を追加します.同時に、最近の10個のオブジェクトを削除します.それを実行すると、Windowsのタスクマネージャの性能ページでPF(ページファイル)の使用状況を観察し、正常であることが分かります.PFの変更使用率はメモリ割り当て効率を示すことができる.
続いて、第二のプログラムを実行して、キューテスト2はもうテスト1と同じ結果になりません.唯一の変動は、各オブジェクトにclick_handlerを追加しました.MozilaとOperaでは、PFの使用は安定していますが、IEではPFが着実に増加し、メモリ漏れは毎秒数メガバイトの増加をもたらします.通常この漏れは注意に値するものではない.しかし、Ajax技術が流行し、1ページの滞在時間が長くなり、ページがより多く変わり、失敗が一般的になりました.
IEはその仕事をうまく行って環状構造を回収できません.この任務は私達の体に落ちました.もし私達がリング機構を明確に壊したら、IEはメモリを回収することができます.マイクロソフトによると、クローズド(closures)は内部エラーの原因となります.これはもちろん重大な誤りですが、マイクロソフトはプログラマーたちに悪い提案をしてマイクロソフトのバグに対処します.これはDOM側から問題が解決しやすい面を閉じて、事実上解決できないJScript側に任せました.
私たちはもう一つのオブジェクトを使用しないと、そのすべてのevent handersをクリアして循環参照を破壊しなければなりません.すべての私たちがしなければならないのは、各event handler属性をnull値に設定することです.これは明確に行うことができますし、または汎用的な浄化関数を書くことができます.
浄化プログラムはDOMオブジェクトをパラメータとして参照します.このサイクル要素のすべての属性は、関数が発見されたら、nullに設定されます.これは循環参照を破壊し、メモリの再生を許可します.これは元素の派生要素でもあります.これは循環参照をよくクリアします.浄化関数はMozillaとOperaに無害で、IEに適用されます.浄化プログラムは、任意の要素を除去する時に呼び出しられ、removeChildメソッドとinnerHTML属性を設定する前に使用します.
function purge(d) {
var a = d.attributes, i, l, n;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
n = a[i].name;
if (typeof d[n] === "function") {
d[n] = null;
}
}
}
a = d.childNodes;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
purge(d.childNodes[i]);
}
}
}
最後に3番目のプログラムを実行します.3列テストを行います.浄化プログラムはDOM元素を削除する前に呼び出されます.説明:メモリ漏れの問題はIE 9まで解決されますので、プログラミングには特に注意してください.
Duglas Crockford原文:JScript Memory Leaks翻訳:blogspot