Javascript + Knockout.js内存泄漏 - 如何确保对象被破坏?

时间:2014-05-01 14:16:08

标签: javascript jquery memory knockout.js memory-leaks

我正在使用google's 3 Snapshot method来查找页面上的内存泄漏。 页面正在Knockout.js和Jquery Mobile UI上运行。 我已经缩小到内存泄漏的div之一。在每个快照之间,我正在运行此脚本以清除内存泄漏对象。

$('.paddedContentContainer').children().each(function(index,item){
console.log(item); 
$(item).off(); 
ko.cleanNode($(item)); 
$(item).remove();
item = null;
});

.paddedContentContainer是泄漏对象的父级 现在有趣的部分是我仍然可以在保留的对象树中看到对象。在下面的屏幕截图中,您可以看到我正在过滤快照3中从快照1和2保留的对象,并且通过文本可以看到$0来自屏幕上同一对象的控制台(事件)销售订单& ....)。 enter image description here

我假设.off();.remove();不足以收集对象。
如何销毁对此对象的所有引用?

3 个答案:

答案 0 :(得分:1)

.remove()只是从DOM中删除元素,如果还有任何引用它(在你的代码中)它将不会被垃圾收集。

修改

是的.remove()是从DOM中分离/删除它的正确方法,但是它仍然保存在内存中,因为其他东西正在引用它(在这个例子中是淘汰赛的内部)。

一种方式,以及我的方式,是保留我在控件中创建的所有高级DOM元素的集合,然后使用destroy函数循环这些元素并在它们上调用.remove()并将它们分配给null

E.g(注意这是在每个控制对象中保存的(没有泄漏的全局内容):

var elements = 
{
    'table' : $('#some_table'),
    'button' : $('#some_button')
};


function destroy()
{
    for(var key in elements)
    {
        elements[key].remove();
        elements[key] = null;
    }
}

您可以通过淘汰赛采取这种方法。

答案 1 :(得分:1)

您是否看过这篇文章:How to destroy a DOM element with jQuery?

卢克的回应似乎很有趣:

  

如果你想完全摧毁目标,你有几个   选项。首先,您可以按照描述从DOM中删除对象   以上...

     

的console.log($目标); // jQuery对象$ target.remove(); //   从DOM console.log($ target)中删除目标; // $目标仍在   存在选项1 - 然后用空的jQuery对象替换target   (jQuery 1.4 +)

     

$ target = $();的console.log($目标); //清空jQuery对象选项2    - 或者完全删除属性(如果你在别处引用它会导致错误)

     

删除$ target;的console.log($目标); //错误:$ target不是   定义

也许你最后应该delete $(item)

答案 2 :(得分:0)

为那些只对knockout.js引用删除感到满意的人添加答案。 这从对象树中移除了<div>

 $('.paddedContentContainer').children().each(function(index,item){
     $(item).off(); 
     ko.removeNode(item);
     $(item).remove();
     item = null;
 });