javascript内存泄漏 [英] javascript memory leaks

查看:87
本文介绍了javascript内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用jquery并做这样的事情

i am using jquery and doing something like this

DOM

<div id="parent"></div>

JS

var _doSomeThing = function()
{
    //some codes
}

$(function()
{
    // appending div and binding methods to span
    $('#parent').append('<span>1</span>');
    $('#parent').append('<span>2</span>');
    $('#parent span').bind('click', _doSomeThing);
});

function _clearDiv()
{
    //clear div
    $('#parent').html('');
}

//sometime in future, call clear div
_clearDiv();

现在我的问题是,绑定事件到 DOM 以后只是从 DOM 中删除​​元素导致内存泄漏?

Now my question is, do binding events to DOM and later just removing the elements from DOM leads to memory leakage?

如果是,请问如何解决这个问题问题?

If yes, how to solve this problem?

推荐答案

jQuery html 方法尝试防止内存泄漏删除由于在jQuery对象上调用 .html('')而删除的任何元素的事件处理程序。

the jQuery html method attempts to prevent memory leaks by removing event handlers for any elements that are deleted as a result of calling .html('') on a jQuery object.

来自1.4.2来源

html: function( value ) {
    if ( value === undefined ) {
        return this[0] && this[0].nodeType === 1 ?
        this[0].innerHTML.replace(rinlinejQuery, "") :
            null;
    } 
    // See if we can take a shortcut and just use innerHTML
    // THE RELEVANT PART
    else if ( typeof value === "string" && !rnocache.test( value ) &&
        (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
        !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {

        value = value.replace(rxhtmlTag, fcloseTag);

        try {
            for ( var i = 0, l = this.length; i < l; i++ ) {
                // Remove element nodes and prevent memory leaks
               if ( this[i].nodeType === 1 ) {
                   jQuery.cleanData( this[i].getElementsByTagName("*") );
                   this[i].innerHTML = value;
                }
            }

        // If using innerHTML throws an exception, use the fallback method
        } 
        catch(e) {
            this.empty().append( value );
        }
    } 
    else if ( jQuery.isFunction( value ) ) {
        this.each(function(i){
            var self = jQuery(this), old = self.html();
            self.empty().append(function(){
                return value.call( this, i, old );
            });
        });

    }
    else {
        this.empty().append( value );
    }
    return this;
}

我们可以看到 jQuery.cleanData() 调用函数。以下是该来源

We can see that the jQuery.cleanData() function is called. Here is the source for that

cleanData: function( elems ) {
    var data, id, cache = jQuery.cache,
        special = jQuery.event.special,
        deleteExpando = jQuery.support.deleteExpando;

    for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
        id = elem[ jQuery.expando ];

        if ( id ) {
            data = cache[ id ];

            if ( data.events ) {
                for ( var type in data.events ) {
                    if ( special[ type ] ) {
                        jQuery.event.remove( elem, type );

                    } else {
                        removeEvent( elem, type, data.handle );
                    }
                }
            }

            if ( deleteExpando ) {
                delete elem[ jQuery.expando ];

            } else if ( elem.removeAttribute ) {
                elem.removeAttribute( jQuery.expando );
            }

            delete cache[ id ];
        }
    }
}

这看起来是 jQuery.cache 对于调用 .html(''时将删除的每个元素的数据对象的events对象属性上的任何事件类型属性的对象)并删除它们。

This looks in the jQuery.cache object for any event type properties on the events object property of the data object relating to each element that will be deleted when calling .html('') and removes them.

基本上解释了标准事件绑定的工作原理,当一个函数绑定为使用jQuery在元素上引发的事件的处理程序时,数据对象被添加为属性为 jQuery.cache 对象。此数据对象包含一个events属性对象,该对象将在其上创建一个属性,其名称与您希望绑定事件处理函数的事件类型相匹配。此属性将包含在元素上引发事件时应调用的函数数组,因此事件处理函数将添加到此数组中。如果这是有问题的事件类型和元素的第一个事件处理函数,那么 jQuery.event.handle 函数调用apply(使用元素作为上下文,如函数执行上下文中的将引用元素)使用 addEventListener / attachEvent 在浏览器中注册。

To basically explain how the standard event binding works, when a function is bound as a handler to an event raised on an element using jQuery, a data object is added as a property to the jQuery.cache object. This data object contains an events property object that will have a property created on it with a name matching the event type to which you wish to bind the event handler function. this property will contain an array of functions that should be called when the event is raised on the element, so the event handler function is added to this array. If this is the first event handler function for the event type and element in question, the jQuery.event.handle function with a call to apply (using the element as the context such that this in the function execution context will refer to the element) is registered with the browser using addEventListener/attachEvent.

当引发事件时, jQuery.event.handle 函数将调用数组中的所有函数在与事件类型匹配的数据对象的events属性对象的属性和引发事件的元素上。

When an event is raised, the jQuery.event.handle function will call all of the functions in the array on the property of the events property object of the data object matching the event type and the element on which the event was raised.

总之, html('')不应该导致内存泄漏,因为有许多防御措施可以阻止它们。

So in summary, html('') shouldn't cause memory leaks as a number of defensive measures are in place to prevent them.

这篇关于javascript内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆