'bound_this'引用的实例不是垃圾回收

Cle*_*Sum 33 javascript memory memory-leaks google-chrome google-chrome-devtools

我有一个关于谷歌浏览器垃圾收集的问题(版本20.0.1132.47,Ubuntu 11.04 64位).

在比较堆转储和检查内存泄漏时,我发现了一些从未清理过的实例.通常这种行为可以追溯到程序员错误,但在这种情况下,我很无能为力..

看一下下面的截图 堆转储的屏幕截图,显示仅由'bound_this'引用的实例(子)

实例'child @ 610739'仅由属于子实例本身的函数的'bound_this'实例引用.所以根据我的理解,子实例应该是垃圾收集的,因为保持它的唯一其他引用是子实例本身(通过'bound_this'函数).

我正在使用underscore.js''bindAll'实用程序函数(underscore.js#bindAll)映射到chrome的'native_bind'函数(bound_this上的ECMA Script wiki)

我是否遗漏了一些明显的东西,如果是这样,有人可以解释是什么让这些实例保持活力?

更新:
同时我测试了相同的应用程序在chrominium(18.0.1025.168(开发人员构建134367 Linux)Ubuntu 11.10),它没有显示这些悬空实例..

更新2:
在Esailijas提示提供一个jsfiddle片段后,我创建了一个(http://jsfiddle.net/8gSTR/1/),模仿我基本上在做什么.不幸的是,运行这个小提琴并没有表明我在申请中遇到的不当行为.尽管引用了window.o数组来保持实例存活,但仍然引用"a"实例时所采用的堆转储看起来有点类似. 在执行上面提到的jsfiddle期间执行的堆转储

因为在我的情况下缺少这样的引用(屏幕截图1)我不知道是什么阻止了chrome释放这些实例...

更新3:
遵循loislos建议以启用隐藏属性.结果(扩展其中一个分支)可以在下面的屏幕截图中看到,但它不会让我更进一步. 启用了隐藏属性的堆转储

小智 4

您对这不是真正的内存泄漏而是 Chrome 的怪异的怀疑是正确的。

我最近遇到了同样的问题。即使您按下收集垃圾按钮 100 次,IE11 也不会将 this.func = _.bind(this.func, this) 显示为内存泄漏,而 chrome 则会显示为内存泄漏。

即使您使用 jsflag 废话运行 chrome 并公开底层垃圾收集器并调用 gc 100 次,它也会显示它。

证明这实际上不是 Chrome 中的泄漏的一个简单方法是,将浏览器的一个小问题变成一个大问题,并强制引擎采取行动。

在分配了绑定函数的实例上分配一个新属性,如下所示:

target.WhyAmILeaking = new Array(200000000).join("YOURNOT");

使用 chrome 执行三快照技术,您将看到堆中存在的字符串大小约为 214mb。再次执行任何建设性操作(第二个快照),您将看到堆达到 423mb 或保持在 214mb。如果它保留下来,那么您就完成了,因为您证明了原始的 214mb 已被收集。如果它不保留,请执行您的破坏性操作(第三个快照),它将返回到 214mb,也证明原始数据已被收集。

如果它只是停留在 423mb,那么先生或女士就有泄漏。

哦,另一群可怜的灵魂也遇到了完全相同的情况:https://github.com/jashkenas/backbone/issues/2269#issuecomment-13610969

TL;博士; 使用 IE 11 检测泄漏。