【问题标题】:How can I find the memory leak in my Javascript?如何在我的 Javascript 中找到内存泄漏?
【发布时间】:2010-10-08 21:36:15
【问题描述】:

我有一个以分页格式显示数据表的应用程序。单击“页面”按钮将重新呈现表格。 (这些不是 HTML 页面 - 这些只是用新的数据“页面”重新填充我的表格的按钮)每个表格单元都有附加的事件处理程序。

出于所有意图和目的,如果应用程序从“第 1 页”开始,我单击“第 2 页”,然后单击“第 1 页”,应用程序的状态应该与此相同的起始条件。

到目前为止,一切都很好。

不幸的是,我注意到(在 Chrome、Firefox 等中)点击不同的“页面”后,我的应用程序正在泄漏内存。

为了找出原因,我点击了 20 个“页面”,然后将我使用的唯一全局控制器对象设置为 null。

这对内存消耗的影响很小。

然后我尝试调用

document.body.remove();

果然,删除了 body 元素,让我没有 HTML。

该应用仍会消耗 20MB 内存 (Chrome)。

我很茫然。当我删除我的全局控制器对象时,应该不再有对它的引用。因为它也是唯一包含对我的数据以及我的所有函数的引用的地方,所以应该释放内存。

当我拍摄堆快照时,我看到了这个:

构造函数 - 引用计数 - 大小

Object  95570   17.69MB
Array   126652  6.14MB
(closure)   72457   5.57MB
klass   57959   1.55MB
String  47461   1.26MB
Arguments   34780   1.06MB
HTMLTableCellElement    15146   709.19KB
HTMLInputElement    14624   685.48KB
(code)  3042    616.88KB
HTMLElement 10459   490.25KB
Variety 2027    132.48KB
HTMLTableRowElement 1242    57.44KB
(anonymous) 11  47.64KB
(global property)   1557    12.16KB
HTMLTableSectionElement 80  2.19KB
HTMLTableElement    41  1.90KB
RegExp  29  1.70KB
HTMLDivElement  46  1.26KB
Console 2   460B
Error   19  456B
d   18  360B
subclass    8   224B
MathConstructor 3   156B

绝大多数这些引用都是闭包(我在我的事件处理程序中使用了很多)。我应该如何寻找内存泄漏?

【问题讨论】:

  • 这是 Mozilla 的泄密工具:wiki.mozilla.org/Performance:Leak_Tools。也许有帮助。
  • 如果我没记错的话,这些工具旨在识别在我的应用程序页面关闭后仍然存在的内存泄漏。我正在尝试修复在我的应用运行时发生的泄漏。
  • 如果点击 20 个“页面”会产生 20MB,那么点击 100 会产生 100MB(或远高于 20MB)吗? Chrome 和 Firefox 使用大量内存来加速 javascript ...
  • 如何重新填充表格?你如何处理被丢弃的行?一页包含多少行?每行有多少个单元格?每行有多少个事件处理程序?您是否考虑过使用事件委托?
  • 回复:Jess - 是的,或多或少。每次点击都会不断增加内存占用。

标签: javascript memory-leaks prototypejs


【解决方案1】:

注意:你不会删除任何东西,你只会从文档树中删除一些东西。删除的节点(主体)仍然是一个 DOM 节点(例如将由 Node->removeChild() 返回,我猜这就是原型在 remove() 中使用的)

我认为没有删除节点的 DOM 方法。

也许您可以尝试其他方法来释放一些内存,例如创建一个 DOM-Range,选择 Node(body) 并删除 Range() 的内容。

此时我没有想到另一种“合法”的方法,在这种情况下我不建议使用 innerHTML。

【讨论】:

  • 删除正文后,document.childNodes 恢复为返回起始页的 HTML(在创建和填充表格之前)。尝试在 body 元素上使用 document.removeChild() 也没有减少我的内存消耗。
【解决方案2】:

我使用drip 来检测内存泄漏

【讨论】:

    【解决方案3】:

    我无法确定泄漏的来源 - 所以我的解决方案是,不是在每次点击页面时重新生成表格的 DOM + 事件处理程序,而是更改表格中元素的值,留下DOM 原封不动。

    这个故事的寓意似乎是你应该非常小心生成 DOM 元素 + 事件处理程序的代码 - 并在它变得太复杂之前测试它是否存在泄漏。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-26
      • 1970-01-01
      • 2018-01-12
      • 2011-01-09
      • 2013-04-04
      • 1970-01-01
      • 1970-01-01
      • 2011-03-28
      相关资源
      最近更新 更多