【发布时间】:2021-06-04 16:29:14
【问题描述】:
通常,在函数中使用关键字“var”定义的 Javascript 变量应该是函数范围的。但我对与 node.js 子进程相关的情况感到困惑。我有两个文件,app.js(主文件)和child.js(子进程的执行脚本):
// app.js
const { fork } = require('child_process');
function bar() {
var child = fork(`${__dirname}/child.js`);
child.on('message', msg => {
console.log("fib(46) = " + msg);
});
}
bar();
gc(); // force the garbage collection
// child.js,计算密集型任务,需要几十秒才能完成
function fib(n) {
return n < 2 ? 1 : fib(n - 1) + fib(n - 2);
}
var result = fib(46);
process.send(JSON.stringify(result));
我期待这段代码可能会抛出一些异常,因为变量“child”是在函数 bar() 中创建的本地对象。当函数 bar() 完成执行时,它应该被垃圾收集。为接收子进程消息而注册的事件处理程序只是保存在'child'对象的哈希表中(子对象也是基于node.js子进程模块文档的EventEmitter的一个实例),所以这些哈希表也应该是垃圾作为被回收的本地“子”对象收集。
但真实情况是,几十秒后,当子进程计算完fib(46)并通过process.send返回结果时,父进程成功发出事件,最终触发注册的事件处理函数:
$ node --expose-gc .\app.js
fib(46) = 2971215073
那么,看起来子进程对象(由局部变量“child”指向的对象)仍在内存中?或者那个子进程对象是node.js子进程模块内部引用的,所以在子进程结束前不能被垃圾回收?我真的需要有人帮我澄清一下情况。
【问题讨论】:
标签: javascript node.js garbage-collection fork child-process