不清楚 V8 垃圾收集

Unclear about V8 Garbage Collection

我很难理解 V8 在 Node.js 中将收集哪些垃圾以及为什么(或为什么不收集)。下面是一个使用 async.js 库的示例。

我很想深入了解 V8 如何处理下面的每个案例(在评论中从 1 到 6 编号)。

提前致谢。

"use strict";

var async = require('async');

module.exports = {

    foo: function foo(shirt, callback) {

        async.series([

            function(next) {

                var pants = 'clown',
                    outfit = shirt + pants;

                // 1. will shirt be garbage collected?

                next(null, outfit);

            },

            function(next) {

                var err = new Error('can\'t touch this.'),
                    pants = 'hammer',
                    outfit = shirt + pants;

                // 2. will shirt be garbage collected?

                setImmediate(function() {

                    // 3. will err be garbage collected?
                    // 4. will outfit be garbage collected?
                    // 5. will next be garbage collected?

                    next(err, outfit);

                })

            }

        ], function(err, results) {

            // 6. will callback be garbage collected?
            callback(err, results);

        });

    }


};

shirt (1, 2) 和 callback (3) 都被内部函数引用。因此它们的绑定必须是堆分配的,并且只有当所有这些内部函数都变成垃圾时才会变成垃圾。在此示例中,这将在 async.series 完成执行并删除其对存储内部函数的数组的引用之后发生。

当然,shirtcallback都是参数。因此,即使 foo 删除了所有对其值的引用,它的调用者可能仍然有一些,在这种情况下,这些值将保持更长时间。你无法在当地知道。

类似地,err (3) 和 outfit (4) 只有在传递给引用它们的 setImmediate 的内部函数变成垃圾时才会变成垃圾(这可能会在它被执行之后发生),并且当 next 将它们传递给的任何延续不再让它们存活时。在此示例中,它们被传递给您一无所知的 callback 参数——它可以通过将它们存储在某个地方或立即删除它们来无限期地保持它们的生命。

最后,next(5)又是一个论据。它的价值至少会持续到 setImmediate 触发。但它是 async.series 创建的一个函数,要知道它的寿命有多长,您还需要详细了解 async.series 是如何处理它的(我假设它会立即删除它)。