垃圾收集如何在JavaScript中工作?
垃圾收集如何在JavaScript中工作? 它与.NET垃圾收集类似吗? 这是因为在VBScript中实施垃圾收集很糟糕,人们避免了它,并建立了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
返回之后,定时器机制也会引用计时器回调,并且定时器回调 - 闭包 - 具有对创建它的上下文的引用,而该回调又包含bar
变量。 因此,理论上,当foo
返回时, bar
所指的内容不能立即用于垃圾收集。 相反,它会一直存在,直到计时器触发并释放其对回调的引用,使回调以及它引用的符合GC的上下文。 (实际上,现代JavaScript引擎可以并且可以优化闭包,例如,在上面的例子中,静态分析显示回调并不涉及bar
,并且不包含任何可能涉及的eval
或new Function
代码它在运行时动态的,所以JavaScript引擎可以放心地离开bar
出来的功能是指上下文,因此使得它指的是符合GC -和现代的一样)。 (关于这篇文章中关闭的更多信息。)
JavaScript没有问题处理清理循环引用,顺便说一句,例如:
function foo() {
var a, b;
a = {};
b = {};
b.refa = a;
a.refb = b;
}
当foo
返回时, a
指的是b
,反之亦然并不是问题。 既然没有别的东西指向他们中的任何一个,他们都可以清理干净。 在IE上,如果其中一个对象是主机提供的对象(如DOM元素或通过new ActiveXObject
创建的东西)而不是JavaScript对象,则这不是真的。 (例如,如果您将JavaScript对象引用放在DOM元素上,而JavaScript对象引用DOM元素,即使没有人引用其中的任何一个,它们也会将内存保留在内存中)。但这是一个IE漏洞,不是JavaScript的东西。
回覆:
是否因为vbscript GC很糟糕,人们将他们转换为标准的客户端API?
JavaScript是原始的客户端Web脚本语言。 VBScript仅在后来才出现,当时微软推出了浏览器,并且只有微软浏览器才支持。 如果你想使用最广泛的浏览器,JavaScript是并且是唯一的客户端脚本游戏。 <主观性>它也是VBScript历史上的八倍。 ;-) </主观>
垃圾收集原则上在所有语言中都使用类似的方法。 然而,它们的实现在不同的环境中会有所不同(例如,每个浏览器使用不同的方式来实现JavaScript GC)。 有关Chrome的GC的简要概述,请参阅此例。
至于VBScript,它被创建为仅在IE中运行的JavaScript对手/替换语言。 在引入VBS时这是一个相当合理的决定 - IE拥有90 +%的浏览器份额,它看起来VBS可以取代(当时广泛支持的,老的和功能差的)JavaScript; 现在不是那么多。 另外,VBScript基本上是Visual Basic Lite,所有负面的内涵都与该品牌相关。
链接地址: http://www.djcxy.com/p/27171.html