我在创建内存泄漏吗?

时间:2012-10-01 18:40:41

标签: javascript memory-leaks

我有一个JavaScript闭包,我会在我的Web应用程序的整个生命周期中重新创建(单个完整的ajax页面)。

我想知道它是否会造成内存泄漏。

以下是JSFIDDLE

的示例

有问题的代码:

function CreateLinks() {

    var ul = $("<ul></ul>").appendTo('div#links');

    for (var i in myLinks) {

        var li = $('<li>' + myLinks[i].name + '</li>').appendTo(ul);

        //closure starts here
        (function (value) {
            li.click(function (e) {
                $('div#info').append('<label>' + value + '</label><br />');
                RecreateLinks();
            });
        })(myLinks[i].value);

    }
}

2 个答案:

答案 0 :(得分:2)

如果您确保避免在click函数中绑定多个RecreateLinks()处理程序,那么您应该没问题。这可以通过显式解除现有的绑定,删除DOM节点或确保不添加多个click处理程序来完成。

浏览器在内存分配策略上越来越好,但你不应该假设太多。如果内存使用是一个很大的问题,请尽量避免创建太多的闭包,而你不确定它们是否会收集垃圾。一种方法是使用.data()来存储您的值对象,然后使用通用的单击处理程序而不是闭包。

分析JavaScript并不那么简单; Chrome确实有一个可以监控CPU和数据性能的配置文件工具。这可以很好地衡量预期的内存消耗量,但Chrome并不是所有浏览器,请记住这一点。

答案 1 :(得分:1)

根据浏览器的智能程度,将“myLinks [i] .value”作为<li>上的属性而不是通过闭包传递可能会更好。当事件处理程序从其范围之外引用变量时,某些愚蠢的浏览器会收集垃圾。 JavaScript和DOM运行两个不同的GC,并且JS没有意识到DOM元素/ eventhandler已经消失,并且该变量不再使用。通过javascript正确删除事件处理程序而不是仅仅处理它所附加的元素,可以解决此问题。

类似于:

li.attr('lvalue',myLinks[i].value);
...
var value = $(this).attr('lvalue');

此设置还允许您使用

$('#links > ul > li').live('click',function(){...});

每次都不需要添加单个事件。