使用开发人员工具识别javascript闭包

时间:2012-12-06 00:38:49

标签: javascript

我目前正在开发一个纯粹的javascript网站,并且在很大程度上依赖于jQuery和amp; jQuery UI库(此站点不适合普通大众使用,因此渐进增强不是此项目的严格要求)。我在执行以下代码时遇到严重的内存泄漏:

oDialogBox = $("<div>...</div>");
/* Add useful things to the dialog box here */
oDialogBox.appendTo("body");
oDialogBox.dialog({
    /* Other dialog box settings here */
    close: function(event, ui) {
        oDialogBox.dialog("destroy");
        oDialogBox.remove();
        oDialogBox = null;
    }
});

在此对话框的任何给定时间,我正在创建,删除和修改大量jQuery UI按钮实例,多选(根据Eric Hynds创建的Multiselect小部件)和单击事件处理程序。根据jQuery UI文档,在oDialogBox 上调用.remove()应该导致所有子窗口小部件被解除绑定并被删除。然而,我的分离的DOM树显示了GC没有收集的大量垃圾元素。

很可能我错过了一大堆需要安全完成的关闭。我如何做到以下几点:

1)如何识别哪个闭包保持给定的分离DOM对象(在Firefox或Chrome中)?

2)假设已经识别出完整的闭包集,是否需要进行除变量之外的任何操作以确保标记DOM元素以进行垃圾收集?

3)我还注意到页面存储的数组列表很大,并且包含对GC未收集的DOM元素的引用。是否有记录的最佳实践从javascript清除数组并允许所有元素被标记为删除? (注意:这是内存泄漏源的当前主要嫌疑人)

1 个答案:

答案 0 :(得分:1)

我担心#1没有很好的答案。我自己没有找到任何真正好的工具,即使过去几年开发工具有多好。我能给出的最好的建议是始终将事物保持在最小的范围内。如果事情没有逃脱,通常更容易弄清楚引用必须在哪里。

对于#2,可能还有其他问题。如果变量v1引用的对象关闭某个函数的自由变量,那么删除v1将不足以使它们符合垃圾收集条件,如果另一个变量v2关闭{{1}在其他一些函数中。所以我想如果你真的是指“完整的闭包”,那么你应该全力以赴。但这可能会变得毛茸茸。同样,如果大多数对象只在狭窄的范围内有参考,那么这些问题就不那么严重了。

对于#3,你在讨论什么类型的数组?如果它是jQuery集合,那么也许你只是有太多它们。我知道让他们长时间呆在一起的唯一原因是将事件处理程序绑定到它们,这几乎总是由父元素上的事件委托更好地处理。如果它是你自己的自定义数组,你真的有充分的理由在数组中存储对它们的引用,这些数组可以持续很长一段时间吗?我很少找到一个。