垃圾收集如何在JavaScript中工作?
垃圾收集如何在JavaScript中工作? 与.NET垃圾收集类似吗? 这是因为在VBScript中垃圾收集的实现是不好的,人们避免了它,并build立了JavaScript作为他们的标准客户端语言的偏好?
垃圾收集如何工作?
简短的回答是:当一块内存(一个对象,比如说)不再可达时,它有资格被回收。 何时,如何或是否被回收完全取决于实施,不同的实施方式是不同的。 但在语言层面上,这是自动的。
例如:
function foo() { var bar; bar = new ReallyMassiveObject(); bar.someCall(); }
当foo
返回时,对象bar
指向自动可用于垃圾回收,因为没有任何内容可以引用它。
对比:
function foo() { var bar; bar = new ReallyMassiveObject(); bar.someCall(); return bar; } // elsewhere var b = foo();
…现在对对象的引用仍然存在,直到/除非调用者给b
或b
指定了其他的内容。
与之相反的是:
function foo() { var bar; bar = new ReallyMassiveObject(); bar.someCall(); setTimeout(function() { alert("Three seconds have passed"); }, 3000); }
在这里,即使在foo
返回之后,定时器机制也具有对定时器callback的引用,并且定时器callback( 闭包 )具有对创build它的上下文的引用,该引用又包含bar
variables。 因此,从理论上讲,当foo
返回时, bar
所指的是什么不能立即用于垃圾收集。 相反,它会一直保持,直到定时器触发并释放对callback的引用,使callback以及引用的符合GC的上下文。 (实际上,现代JavaScript引擎可以并且可以优化闭包,例如,在上面的例子中,静态分析显示callback并不涉及bar
,并且不包含任何eval
或new Function
代码,可能涉及到它在运行时是dynamic的,所以JavaScript引擎可以安全的离开函数引用的上下文,从而使得它引用的符合GC的条件 – 现代的)。 (更多关于这篇文章中closures。)
JavaScript没有问题处理清理循环引用,顺便说一句,例如:
function foo() { var a, b; a = {}; b = {}; b.refa = a; a.refb = b; }
当foo
返回时, a
指的是b
,反之亦然并不是问题。 既然没有别的东西指向他们中的任何一个,他们都可以清理干净。 在IE上,如果其中一个对象是主机提供的对象(如DOM元素或通过new ActiveXObject
创build的东西)而不是JavaScript对象,则这不是真的。 (例如,如果你把一个JavaScript对象引用放在一个DOM元素上,并且JavaScript对象引用DOM元素,那么即使没有人引用其中的任何一个,它们也会互相保留)。但这是IE 错误的 问题 ,而不是JavaScript的东西。
回覆:
是不是因为vbscript GC不好,人们回到了JavaScript作为他们的标准客户端API?
JavaScript是原始的客户端网页脚本语言。 VBScript只是后来才出现的,当时微软推出了浏览器,并且只在微软的浏览器中被支持。 如果你想使用最广泛的浏览器,那么JavaScript就是并且是城里唯一的客户端脚本游戏。 这也是VBScript语言的八倍之多。 😉 </主观>
垃圾收集原则上在所有语言中使用类似的方法。 然而,他们的实现在不同的环境中是不同的(例如,每个浏览器使用不同的方式来实现JavaScript GC)。 有关Chrome浏览器GC的简要概述,请参阅此例 。
至于VBScript,它被创build为只能在IE中运行的JavaScript对手/replace语言。 在VBS推出的时候,这是一个相当合理的决定 – IE浏览器共享了90%以上的浏览器份额,而且看起来VBS可以取代当时被广泛支持的,function较差的JavaScript; 不是现在这么多 而且,VBScript基本上是Visual Basic Lite,所有负面的内涵都与该品牌相关。