7

我目前正在开发一个纯 javascript 的网站,并且严重依赖 jQuery 和 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 创建的多选小部件)和单击事件处理程序的实例。根据 jQuery UI 文档,在 oDialogBox 上调用 .remove()应该会导致所有子小部件被解除绑定和删除。然而,我分离的 DOM 树显示了 GC 没有收集的大量垃圾元素。

我很可能错过了大量需要安全完成的关闭。如何执行以下操作:

1) 如何识别哪些闭包使给定的分离 DOM 对象保持活动状态(在 Firefox 或 Chrome 中)?

2) 假设确定了完整的闭包集,除了使变量为空之外,是否需要做任何事情来确保将 DOM 元素标记为垃圾回收?

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

4

1 回答 1

1

恐怕我对#1没有很好的答案。我自己还没有找到任何真正好的工具,即使考虑到过去几年开发工具已经变得多么好。我能给出的最好建议是始终将事情保持在尽可能小的范围内。如果事情没有逃脱,通常更容易找出引用必须在哪里。

至于#2,可能会有更多的担忧。如果变量引用的对象v1关闭了某个函数的空闲变量,如果另一个变量在某个其他函数中关闭,则删除v1将不足以使它们有资格进行垃圾收集。所以我想如果你真的是指“完整的闭包集”,那么你应该已经准备好了。但这可能会让人毛骨悚然。同样,如果大多数对象仅在狭窄范围内具有引用,则这些问题的严重性要小得多。v2v1

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

于 2012-12-06T01:09:20.917 回答