我需要一些帮助来解决这是如何工作的(或者不是这样)。
var classInstance
是实例,我可以像classInstance.rootNode
那样访问节点。classInstance
关闭并将ajax响应传递给classInstance
并使用它来修改rootNode
的样式或内容或其他。我的问题是,一旦我完成classInstance
,假设没有其他任何东西引用它本身,它在其自己的闭包中没有任何其他东西,垃圾收集器会处理它吗?如果没有,我该如何标记它以供处置?
答案 0 :(得分:6)
为了回应@ Beetroot-Beetroot的疑虑(不可否认,我也有),我做了一些挖掘。我设置了this fiddle,并使用chrome dev-tools' timeline和this article作为指导。在小提琴中,两个几乎相同的处理程序创建一个带有2个日期对象的闭包。第一个仅引用a
,第二个引用a
和b
。虽然在这两种情况下都只能真正暴露a
(硬编码值),但第一个闭包使用的内存要少得多。无论是JIC(只是及时编译)还是V8的JS优化魔法,我都不能肯定。但是从我读过的内容来看,我会说V8的GC在b
函数返回时解除分配tst
,而在第二种情况下则不能bar
引用{{ 1}} b
返回时)。我觉得这不是那么古怪,我一点都不会惊讶地发现FF甚至IE都会有类似的工作。
只是为了完整性而添加了这个,也许是无关紧要的更新,因为我觉得google文档中dev-tools的链接是增值的。
这有点依赖,作为一个简单的经验法则:只要你不能再引用tst2
变量,它就应该是GC,而不管它自己的循环引用。我已经测试了很多结构,类似于你在这里描述的结构。也许it's worth a look我发现封闭和内存泄漏并不常见或容易过去(至少,不再是)。
但正如接受的答案所说:几乎不可能知道什么时候会泄漏什么代码。
再次阅读你的问题,我会说:不,你不会泄漏内存:classInstance
变量不是在全局范围内创建的,而是传递给各种函数(因此各种范围)。每次函数返回时,这些范围都会分解。 classInstance
如果已被传递到另一个函数/范围,则不会被GC。但是,只要引用classInstance
的最后一个函数返回,该对象就会标记为GC。当然它可能是一个循环引用,但它是一个参考,不能从任何地方访问,但它自己的范围。
你也不能真正称之为闭包:当外部范围存在某种形式的曝光时会发生闭包,这在你的例子中没有发生。
我在解释这样的东西时很垃圾,但回顾一下:
classInstance
GC会释放mem var foo = (function()
{
var a, b, c, d;
return function()
{
return a;
}
})();
,b
和c
引用:它们已超出范围,无法访问它们......
d
在这种情况下,由于显而易见的原因,var foo = (function()
{
var a, b, c, d;
return function()
{
a.getB = function()
{
return b;
}
a.getSelf = function()
{
return a;//or return this;
}
return a;
}
})();
//some code
foo = new Date();//
也不会获得GC。 b
公开foo
和a
,其中b
是包含循环引用的对象。虽然只要a
,foo = new Date()
就会失去对foo
的任何引用。当然,a
仍然引用自己,但a
不再暴露:它可以引用它喜欢的任何东西。大多数浏览器都不会关心GC a
和a
。事实上,我已经检查过Chrome,FF,和 IE8所有GC上面的代码完全正确......不用担心,那么。
答案 1 :(得分:1)
我不是这个问题的专家,但我很确定GC 不会处理它。实际上,它可能永远不会,因为您在事件侦听器和DOM节点之间创建了一个循环引用。要允许它被垃圾收集,您应该将这些引用(事件监听器和/或rootNode)中的一个或两个设置为undefined或null。
但是,如果您正在创建许多这样的类实例,或者如果它可以在页面的生命周期内多次创建,我只会担心这一点。否则,这是一项不必要的优化。