jQuery泄漏解决了,但为什么呢?
jQuery leaks solved, but why?
我正在开发一个大型企业应用程序,其中包含大量JavaScript。我无法一一解释并修复过去5年开发过程中出现的所有循环引用。在研究解决方案时,我遇到了这个jQuery小hack/补丁:
http://kossovsky.net/index.php/2009/07/ie-memory-leak-jquery-garbage-collector/并决定尝试一下。令人惊讶的是,它居然有效!sIEVE在我之前确定的地方没有显示泄漏,并且iexplore任务正在维护更易于管理的内存占用。
我的问题是,为什么这个工作?jQuery。remove调用. removechild,它应该删除元素,但显然没有。相反,补丁将目标元素附加到一个新的垃圾收集器div上,然后将其清除。为什么移除的patch方法可以完全释放内存,而jQuery的移除函数却不能?我希望理解为什么这样做,以便在我将其签入到更大的应用程序之前可能改进解决方案。
这是当前jQuery版本(1.6.2)中的.remove
方法。注意它调用了.cleanData
:
// keepData is for internal use only--do not document
remove: function( selector, keepData ) {
for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
if ( !keepData && elem.nodeType === 1 ) {
jQuery.cleanData( elem.getElementsByTagName("*") );
jQuery.cleanData( [ elem ] );
}
if ( elem.parentNode ) {
elem.parentNode.removeChild( elem );
}
}
}
return this;
},
和它调用的.cleanData
方法,它提到一个票号,据称可以防止可怕的泄漏(根据其中一个评论):
cleanData: function( elems ) {
var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
deleteExpando = jQuery.support.deleteExpando;
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
continue;
}
id = elem[ jQuery.expando ];
if ( id ) {
data = cache[ id ] && cache[ id ][ internalKey ];
if ( data && data.events ) {
for ( var type in data.events ) {
if ( special[ type ] ) {
jQuery.event.remove( elem, type );
// This is a shortcut to avoid jQuery.event.remove's overhead
} else {
jQuery.removeEvent( elem, type, data.handle );
}
}
// Null the DOM reference to avoid IE6/7/8 leak (#7054)
if ( data.handle ) {
data.handle.elem = null;
}
}
if ( deleteExpando ) {
delete elem[ jQuery.expando ];
} else if ( elem.removeAttribute ) {
elem.removeAttribute( jQuery.expando );
}
delete cache[ id ];
}
}
}
这是评论中提到的票。显然它在八个月前就被修复了:
http://bugs.jquery.com/ticket/7054评论:10
根据Dave Methvin的解决方案似乎是确保事件处理程序中的DOM元素ref被cleanData删除,以避免IE6/7/8内存泄漏
换句话说,将事件处理程序中对DOM元素的引用设置为null
,否则一些很棒的浏览器,不提及任何名称cough IE cough会泄漏内存。
discardElement
(来自您的链接)将元素插入容器,然后清空容器,因此使对该元素的任何引用无效。
考虑到这一点,我建议升级jQuery。您所指的这篇文章是2009年的,两年的时间大致相当于jQuery的四亿个小时的开发时间。
最后,这里是一些有趣的(和荒谬的长)阅读在Internet Explorer泄漏模式:
- 了解和解决Internet Explorer泄漏模式
我认为它类似于。net垃圾收集,因为它依赖于堆中的固定对象。
IE将被删除对象的父对象视为大头针,而没有正确清除被删除的对象。
将删除的项移动到这个生成的gc容器的行为基本上是移除pin,因为IE知道没有任何东西依赖于该容器。
这就是我的直觉
- 为什么我的函数没有被调用呢
- 为什么不在浏览器上获得JQuery效果呢
- Redux:为什么不把操作和reducer放在同一个文件中呢
- jquery ui 有什么用途?为什么不使用jQuery呢?
- 页面刷新后javascript内存泄漏有问题吗?为什么?
- 两个javascript网络工作者连续打印输出-为什么不同时打印呢
- JSLint errors on 'new function(){..}'但为什么呢?如果我想要匿名关闭
- 我的查询获胜'因为一个剧本,它不能工作(它以错误的方式工作)!?但为什么呢?SESSIONS和PHP
- 根据Javascript,DIV的宽度不算什么,为什么呢
- 为什么呢?Else块只工作一次
- 将JavaScript对象序列化为JSON返回“{}}”,但是为什么呢?
- 动态创建复选框单击事件,选择整行,而不仅仅是jquery数据表中的复选框.为什么呢?
- 在应用dequeue()之前,多个动画不会在jQuery queue()上运行,为什么呢?
- 我得到了错误:太多的递归.为什么呢?
- 子类不起作用,为什么呢?
- jQuery泄漏解决了,但为什么呢?
- Chrome扩展窗口.历史失败了,但为什么呢?
- jQuery .text()返回NaN,为什么呢?
- JavaScript没有按照我的要求去做!为什么呢?
- jQuery上的函数被绑定到容器,为什么呢?