我正在使用requestAnimationFrame循环构建一个游戏,其中包含一个jQuery html()方法的调用.它只是更新游戏操作旁边的状态窗口中的文本.
我注意到Chrome的时间轴监视器,DOM节点上升和上升,几分钟内!当我更改我的代码时:
// creates a ton of DOM nodes $("#readout").html(data);
至
// DOM nodes does not increase over time document.getElementById('readout').innerHTML = data;
“内存泄漏”消失.
解决方法
简答:不.
内存泄漏通常由Javascript引擎和DOM之间的循环引用引起.例如:
var div = document.getElementById('divId'); div.onclick = function() { doSomething(div); };
脚本获取对页面上的div的引用.到目前为止,我们没事.下一行将为DOM上的事件处理程序分配一个函数,从DOM到Javascript引擎创建一个引用 – 一半的泄漏.函数体使用标签,它创建一个Closure – 标签引用保留有将来调用的函数.这完成了标签之间的循环引用 – >函数(DOM – > JS)和函数 – >标签(JS – > DOM),所以2将坐在内存中,直到浏览器的进程被销毁.
所以为了你提到的任何一行代码泄漏,它必须要消除那些像上面那样附带的事件的标签(或类似模式的数据).但是,jQuery的.html(字符串)已经不能阻止这些:
// Remove element nodes and prevent memory leaks elem = this[i] || {}; if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem,false ) ); elem.innerHTML = value; }
所以它循环遍历你正在运行的标签中的所有标签.html(string),并在其上运行cleanData(),这反过来又做:
jQuery.removeEvent( elem,type,data.handle );
从而防止泄漏.
所以为了通过这种方法泄漏内存,而不是浏览器内置的.innerHTML,你必须触发一些非常模糊的浏览器错误(似乎不大可能),或者更有可能是其他事情发生,你错了对于jQuery的.html(字符串).