私のJavaSriptコードは、LI
要素のリストを作成します。リストを更新すると、メモリ使用量が増加し、ダウンすることはありません。 sIEveでテストしたところ、ブラウザーは$.remove()
または$.empty
jQueryコマンドによって削除されるはずのすべての要素を保持していることがわかります。
メモリリークなしでDOMノードを削除するにはどうすればよいですか?
特定のコードについては my other question をご覧ください。
DOMはすべてのDOMノードを保持します。DOMツリー自体から削除された場合でも、これらのノードを削除する唯一の方法はページの更新を行うことです(リストをiframeに入れた場合、更新はそれほど顕著ではありません)
それ以外の場合、ブラウザのガベージコレクターが強制的に動作するように問題が悪化するのを待つことができます(ここでは数百メガバイトの未使用ノードと通信しています)
ベストプラクティスは、ノードを再利用することです。
編集:これを試してください:
var garbageBin;
window.onload = function ()
{
if (typeof(garbageBin) === 'undefined')
{
//Here we are creating a 'garbage bin' object to temporarily
//store elements that are to be discarded
garbageBin = document.createElement('div');
garbageBin.style.display = 'none'; //Make sure it is not displayed
document.body.appendChild(garbageBin);
}
function discardElement(element)
{
//The way this works is due to the phenomenon whereby child nodes
//of an object with it's innerHTML emptied are removed from memory
//Move the element to the garbage bin element
garbageBin.appendChild(element);
//Empty the garbage bin
garbageBin.innerHTML = "";
}
}
コンテキストで使用するには、次のようにします。
discardElement(this);
これは実際の答えよりも[〜#〜] fyi [〜#〜]ですが、非常に興味深いものです。
W3CからDOMコア仕様(http://www.w3.org/TR/DOM-Level-2-Core/core.html):
Core DOM APIは、一般ユーザーのスクリプト言語と、主にプロのプログラマーが使用するより困難な言語の両方を含む、幅広い言語と互換性があるように設計されています。したがって、DOM APIは、明示的なコンストラクターを提供するが自動ガベージコレクションメカニズムを自動的に提供する(特にJava)を通じて、ユーザーにメモリ管理をまったく公開しない言語バインディングから、さまざまなメモリ管理哲学にわたって動作する必要があります未使用のメモリを、特にプログラマがオブジェクトメモリを明示的に割り当て、使用場所を追跡し、再利用のために明示的に解放する必要がある(特にC/C++)メモリに再利用します。これらのプラットフォーム間で一貫したAPIを確保するために、DOMはメモリ管理の問題にまったく対処せず、代わりにこれらを実装に任せます。 DOM API(ECMAScriptおよびJava用)で定義された明示的な言語バインディングのいずれもメモリ管理メソッドを必要としませんが、他の言語(特にCまたはC++)のDOMバインディングはそのようなサポートを必要とします。これらの拡張機能は、DOM APIをDOMワーキンググループではなく特定の言語に適応させる人の責任となります。
つまり、メモリ管理は、さまざまな言語でのDOM仕様の実装に任されています。 JavaScriptでDOM実装のドキュメントを調べて、メモリからDOMオブジェクトを削除する方法を見つける必要がありますが、これはハックではありません。 (ただし、そのトピックに関するMDCサイトにはほとんど情報がありません。)
jQuery#remove
およびjQuery#empty
に関するメモ:これらのメソッドのどちらからも、DOM Object
sからnode
sを削除するか、DOM node
sを削除する以外のことはできませんdocument
から。削除するだけですもちろん、これらのオブジェクトにdocument
にないメモリが割り当てられているわけではありません。
編集:上記の文章は、jQueryが驚くことをすることができず、使用されているブラウザーのDOM実装を回避することができないため、余分です。
イベントリスナーを削除しましたか? メモリリークを引き起こす可能性があります 。
リークを「後修正」する必要があり、クロージャ、循環参照などを考慮してすべてのコードを書き換えずに行う必要がある場合は、削除する前にダグラス・クロックフォードのパージ方法を使用します。
http://javascript.crockford.com/memory/leak.html
または、次のクロージャ修正の回避策を使用します。