找到分离的DOM树内存泄漏

Raf*_*afe 22 html javascript memory-leaks google-chrome

我在主要使用Knockout构建的非常大的单页Web应用程序中诊断分离的DOM树内存泄漏时遇到了问题.

我已经调整了应用程序,将虚拟FooBar对象附加到特定的HTML按钮元素,当用户移动到应用程序的不同"页面"时,该元素应该被垃圾收集.使用Chrome的堆快照功能,我可以看到一个旧的FooBar实例(应该是GC)仍然可以从HTMLButtonElement(大)分离的DOM树中访问它.

通过保留树面板跟踪参考,我跟随链从GC根部减少距离.但是,在某些时候,我的搜索在离根的节点距离4处达到死胡同(在这种情况下)!保留树根本不报告对此节点的引用,但不知何故知道它是GC根目录的四个步骤.

这是保留树的一部分让我感到困惑(右边的数字是距离根部的距离):

v foobar in HTMLButtonElement                                  10
  v [4928] in Detached DOM tree / 5643 entries                  9
    v native in HTMLOptionElement                               8
      v [0] in Array                                            7
        v mappedNodes                                           6
          v [870] in Array                                      5
            v itemsToProcess in system / Context                4
                context in function itemMovedOrRetained()
                context in function callCallback()
Run Code Online (Sandbox Code Playgroud)

保留树在距离3或以上不显示参考.

任何人都可以向我解释这个吗?我希望我能够跟随参考链回到JavaScript应用程序代码中令人讨厌的部分 - 但这让我陷入困境!

nau*_*tur 13

首先 - 不要使用delete建议的评论之一.设置引用null是处理事物的正确方法.delete打破了"隐藏的阶级".要自己查看,请从https://github.com/naugtur/js-memory-demo运行我的示例

Rafe,你在profiler中看到的内容通常很难理解.你在这里发布的那个看起来很奇怪,可能是你的应用程序之外的一个bug或内存泄漏(浏览器泄漏),但是没有运行你的应用程序很难说.保留树在函数的上下文中结束,并且可以通过对该函数的引用或共享上下文的某个其他函数来保留.对于探查器来说,正确地可视化它可能太复杂了.

我可以帮你找出问题所在.

首先,转到devtools中的Timeline选项卡,并使用它来观察泄漏发生的时刻.仅选择内存分配并开始录制.浏览一下您希望泄漏的场景.保持蓝色的条纹是泄漏.您可以在时间轴中选择它们的周围环境,并专注于它们的保留树.分离的dom树中最有趣的元素是红色的 - 它们是从外部引用的.其余的保留,因为引用了树中的任何元素,它引用了其他所有内容(x.parentNode)

如果您需要更多的细节,你可以采取多个快照的探查,让你之前和泄漏的原因之后有一个快照(您发现时间轴 - 现在你知道导致它的确切作用).然后,您可以比较分析器中的那些 - 这是一个"比较"视图.这比其他人更容易理解.

您还可以从分析器中保存堆快照并在线发布,因此我们可以看一看.左侧列表中的每个都有一个保存链接.


分析内存很难,实际上需要一些练习和对工具的理解.你可以从我的演讲中练习一些例子:

http://naugtur.pl/pres/mem.html#/5/2

但使用内存分析器的真正完整指南是这个doc:

https://developer.chrome.com/devtools/docs/javascript-memory-profiling#looking_up_color_coding

更新链接: https ://developers.google.com/web/tools/profile-performance/memory-problems/memory-diagnosis

  • 但是,如果你只有红色节点怎么办? (3认同)