Javascript jQuery漏洞已经解决,但为什么?

Javascript jQuery漏洞已经解决,但为什么?,javascript,jquery,dom,Javascript,Jquery,Dom,我正在使用大量JavaScript开发一个大型企业应用程序。足够了,我不可能通过并修复在过去5年的开发中创建的所有小循环引用。在研究解决方案时,我遇到了一个小小的jQuery黑客/补丁: 决定试试看。令人惊讶的是,它的工作!sIEVE显示在我之前识别的位置没有泄漏,iexplore任务正在保持更易于管理的内存占用 我的问题是,为什么这样做?remove calls.removeChild,它应该去掉元素,但显然没有。该补丁将目标元素附加到一个新的垃圾收集器div上,然后将其清除。为什么删除的补

我正在使用大量JavaScript开发一个大型企业应用程序。足够了,我不可能通过并修复在过去5年的开发中创建的所有小循环引用。在研究解决方案时,我遇到了一个小小的jQuery黑客/补丁:

决定试试看。令人惊讶的是,它的工作!sIEVE显示在我之前识别的位置没有泄漏,iexplore任务正在保持更易于管理的内存占用


我的问题是,为什么这样做?remove calls.removeChild,它应该去掉元素,但显然没有。该补丁将目标元素附加到一个新的垃圾收集器div上,然后将其清除。为什么删除的补丁方法完全释放了内存,而jQuery的删除函数却没有?我希望在将解决方案签入到更大的应用程序之前,能够理解为什么这样做可以改进解决方案。

我将从理论上证明它类似于.net垃圾收集,因为它依赖于堆中的固定对象

IE将移除对象的父对象视为pin,而没有正确地清除移除对象

将已删除的项目移动到此生成的gc容器的行为基本上就是删除pin,因为IE知道没有任何东西依赖于该容器


这是我的直觉。

这是当前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
方法,该方法提到了一个票证号码,据称防止了可怕的泄漏(根据其中一条评论):

这是评论中提到的罚单。显然,它是八个月前修复的:

Dave Methvin认为,解决方案似乎是确保cleanData删除事件处理程序中的DOM元素ref,以避免IE6/7/8内存泄漏

换句话说,将事件处理程序中对DOM元素的引用设置为
null
,否则一些很棒的浏览器会泄漏内存,而不提及任何名称

discardeElement
(从链接)将元素插入容器,然后清空容器,从而使对该元素的任何引用无效

考虑到这一点,我建议升级jQuery。您所指的这篇文章是从2009年开始的,两年大约相当于400亿工时的jQuery开发时间

最后,这里有一些有趣的(而且长得可笑)关于Internet Explorer中泄漏模式的阅读:


不幸的是,我无法合理地遍历整个代码库,寻找空的事件处理程序。这就是为什么我对这个黑客解决方案感兴趣。到目前为止,它已被证明是一个银弹,不需要手动将处理程序设置为null。@JPRO-不是事件处理程序,事件处理程序中的DOM元素,如果您愿意将jQuery升级到更新的版本,则不必这样做。当然,坏代码是问题的主要原因,我可以仔细检查并纠正它,但这将花费比我分配给这项任务更多的时间。我们目前正在使用jQuery 1.6.2。这就是说,我想你已经回答了为什么这样做的问题(我自己也得出了同样的结论,但需要更多的投入)。谢谢你的信息!回答得好,我很高兴实际情况与我的想法没有太大的距离,也就是说,一个参考(pin)正在使IE不破坏对象。这个答案做得很好,经过仔细的研究和打字,+1
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 ];
            }
        }
    }