如何删除没有内存泄漏的DOM元素?

我的JavaSript代码构build了LI元素的列表。 当我更新列表时,内存使用量增长,永远不会下降。 我在sIEve中进行了testing,结果表明浏览器保留了所有被$.remove()$.empty jQuery命令删除的元素。

我应该怎么做,没有内存泄漏删除DOM节点?

看到我的其他问题的具体代码。

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); 

这是一个比实际答案更多的参与,但也是相当有趣的。

从W3C DOM核心规范http://www.w3.org/TR/DOM-Level-2-Core/core.html):;

核心DOM API被devise为与广泛的语言兼容,包括通用用户脚本语言和主要由专业程序员使用的更具挑战性的语言。 因此,DOM API需要通过各种内存pipe理理念进行操作,从不提供内存pipe理的语言绑定到通过提供显式构造函数但提供自动垃圾收集机制来自动执行的那些(特别是Java)回收未使用的内存,那些通常需要程序员明确分配对象内存,跟踪它的使用位置,并明确释放它重用的那些(特别是C / C ++)。 为了确保这些平台上的API一致,DOM并没有解决内存pipe理问题,而是留下了这些实现。 DOM API(用于ECMAScript和Java)定义的显式语言绑定都不需要任何内存pipe理方法,但其他语言(特别是C或C ++)的DOM绑定可能需要这种支持。 这些扩展将是那些将DOM API调整为特定语言的职责,而不是DOM工作组。

换句话说:内存pipe理留给了各种语言的DOM规范的实现。 您将不得不在JavaScript中查看DOM实现的文档,以找出从内存中删除DOM对象的任何方法,这不是一个破解。 (然而,关于该主题的MDC网站上的信息很less。)


作为关于jQuery#removejQuery#empty :从我所知道的这些方法中,除了从DOM node删除Object或从document删除DOM node之外,没有任何其他的方法。 他们只是删除这当然并不意味着没有内存分配给这些对象(即使他们不在document了)。

编辑:上面的段落是多余的,因为显然jQuery不能做奇迹,并围绕使用的浏览器的DOM实现工作。

你有没有删除任何事件监听器? 这可能会导致内存泄漏 。

下面的代码不会泄漏我的IE7和其他浏览器:

 <html> <head></head> <body> <a href="javascript:" onclick="addRemove(this)">add</a> <ul></ul> <script> function addRemove(a) { var ul = document.getElementsByTagName('UL')[0], li, i = 20000; if (a.innerHTML === 'add') { while (i--) { li = document.createElement('LI'); ul.appendChild(li); li.innerHTML = i; li.onclick = function() { alert(this.innerHTML); }; } a.innerHTML = 'remove'; } else { while (ul.firstChild) { ul.removeChild(ul.firstChild); } a.innerHTML = 'add'; } } </script> </body> </html> 

也许你可以尝试找出你的代码的一些差异。
我知道,在你做任何事情之前先插入DOM中的节点,比如:将事件附加到它或者填充它的innerHTML属性,IE的泄漏就会less得多。

如果您必须“修复”泄漏,并且必须在不重写所有代码的情况下进行修复,例如在删除之前使用Douglas Crockfords清除方法:

http://javascript.crockford.com/memory/leak.html

或者使用这个closures修复解决方法:

http://laurens.vd.oever.nl/weblog/items2005/closures/