垃圾收集如何在JavaScript中运行?

时间:2010-12-01 12:02:40

标签: javascript vbscript garbage-collection

垃圾收集如何在JavaScript中运行?它与.NET垃圾收集类似吗?是因为在VBScript中实现垃圾收集是不好的,人们避开它并建立了JavaScript作为标准客户端语言的偏好?

2 个答案:

答案 0 :(得分:78)

  

垃圾收集如何运作?

简短的回答是:当一块内存(比如一个对象)不再可达时,它就有资格被回收。它何时,如何或是否被回收完全取决于实现,并且不同的实现以不同的方式进行。但在语言层面,它是自动的。

例如:

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();

...现在对该对象的引用在通话中幸存,并持续到/除非调用者将其他内容分配给bb超出范围。

与之相反:

function foo() {
    var bar;

    bar = new ReallyMassiveObject();
    bar.someCall();
    setTimeout(function() {
        alert("Three seconds have passed");
    }, 3000);
}

这里,即使在foo返回之后,计时器机制也会引用计时器回调,而计时器回调 - 闭包 - 会引用它创建的上下文,而后面包含bar变量。因此,理论上,当bar返回时,foo引用的内容不能立即用于垃圾回收。相反,它一直保持到计时器触发并释放其对回调的引用,使得回调及其引用的上下文符合GC的条件。 (实际上,现代JavaScript引擎可以并且尽可能地优化闭包。例如,在上面,静态分析显示回调不引用bar,并且不包含任何eval或者new Function代码可以在运行时动态引用它,因此JavaScript引擎可以安全地将bar从函数引用的上下文中移出,从而使其符合GC的条件 - 而现代的做)。 (关于this article中闭包的更多信息。)

JavaScript处理清理循环引用时没有问题,顺便说一句,例如:

function foo() {
    var a, b;

    a = {};
    b = {};
    b.refa = a;
    a.refb = b;
}

foo返回时,a引用b反之亦然的事实不是问题。由于没有其他任何内容涉及它们中的任何一个,它们都可以被清理。在IE上,如果其中一个对象是主机提供的对象(例如DOM元素或通过new ActiveXObject创建的内容)而不是JavaScript对象,则为true。 (例如,如果你把一个JavaScript对象引用放在一个DOM元素上,并且JavaScript对象引用回DOM元素,那么即使没有人引用它们中的任何一个,它们也会在内存中相互保留。)但这是一个IE bug 问题,而非JavaScript事物。

回复:

  

是因为vbscript GC很糟糕,人们还原为javascript作为标准的客户端API?

JavaScript是原始客户端Web脚本语言。 VBScript仅在微软推出浏览器后才出现,并且只在微软浏览器中得到支持。如果你想使用最广泛的浏览器,JavaScript曾经并且是城里唯一的客户端脚本游戏。 <主观>它也是VBScript经典语言的八倍。 ;-)< / subjective>

答案 1 :(得分:2)

原则上,

Garbage collection在所有语言中使用类似的方法。然而,它们的实现在不同环境中是不同的(例如,每个浏览器使用不同的方式来实现JavaScript GC)。有关Chrome的GC的简要概述,请参阅例如this

对于VBScript,它是作为JavaScript竞争对手/替换语言创建的,只能在IE中运行。在引入VBS时,这是一个相当合理的决定 - IE拥有90%以上的浏览器份额,看起来VBS可以取代(当时广泛支持的,功能较旧且功能较差的)JavaScript;现在不是那么多。此外,VBScript基本上是Visual Basic Lite,具有该品牌的所有负面内涵。

相关问题