javascript – V8是否在范围的各个部分上进行垃圾收集?

我对V8是否对范围内的各个变量的内容进行垃圾收集,或者它是否只对整个范围进行垃圾收集感兴趣?

所以,如果我有这个代码:

function run() {
    "use strict";
    var someBigVar = whatever;
    var cnt = 0;

    var interval = setInterval(function() {
        ++cnt;
        // do some recurring action
        // interval just keeps going
        // no reference to someBigVar in here
    }, 1000);

    someBigVar = somethingElse;
}

run();

V8垃圾会收集一些BigVar吗?由于setInterval()回调,run()中的闭包仍然存活,显然cnt变量仍然被使用,因此run()的整个范围不能被垃圾回收.但是,没有实际的持续参考someBigVar.

V8只垃圾一次收集整个范围吗?那么,在间隔停止之前,run()的范围不能被垃圾收集?或者它是否足够智能垃圾收集someBigVar,因为它可以看到间隔回调中没有实际引用someBigVar的代码?

仅供参考,这是一个interesting overview article on V8 garbage collection(它没有解决这个具体问题).

最佳答案 是的,它确实.仅保留在闭包内实际使用的变量.否则,闭包必须捕获外部作用域中定义的所有内容,这可能很多.

唯一的例外是如果在闭包内使用eval.由于无法静态确定eval参数所引用的内容,因此引擎必须保留所有内容.

这是一个使用weak模块演示此行为的简单实验(使用–expose-gc标志运行):

var weak = require('weak');
var obj = { val: 42 };

var ref = weak(obj, function() {
  console.log('gc');
});

setInterval(function() {
  // obj.val;
  gc();
}, 100)

如果封闭内部没有引用ref,你会看到gc打印出来.

点赞