Node.js v8/Node是否在函数调用期间进行垃圾收集?-或者这是sailsJS的内存泄漏
我正在创建一个sailsJS Web服务器,其后台任务需要连续运行(如果服务器空闲)。-这是一项将数据库与一些外部数据和预缓存数据同步以加速请求的任务 我使用的是sails 1.0版。t适配器是postgresql(Node.js v8/Node是否在函数调用期间进行垃圾收集?-或者这是sailsJS的内存泄漏,node.js,memory-leaks,sails.js,v8,Node.js,Memory Leaks,Sails.js,V8,我正在创建一个sailsJS Web服务器,其后台任务需要连续运行(如果服务器空闲)。-这是一项将数据库与一些外部数据和预缓存数据同步以加速请求的任务 我使用的是sails 1.0版。t适配器是postgresql(适配器:'sails-postgresql'),适配器版本:1.0.0-12 现在,在运行这个应用程序时,我注意到了一个主要问题:似乎过了一段时间,应用程序会莫名其妙地崩溃,出现堆外内存错误。(我甚至无法捕捉到这一点,节点进程刚刚退出) 当我试图寻找内存泄漏时,我尝试了许多不同的方法
适配器:'sails-postgresql'
),适配器版本:1.0.0-12
现在,在运行这个应用程序时,我注意到了一个主要问题:似乎过了一段时间,应用程序会莫名其妙地崩溃,出现堆外内存错误。(我甚至无法捕捉到这一点,节点进程刚刚退出)
当我试图寻找内存泄漏时,我尝试了许多不同的方法,最终我可以将代码简化为以下函数:
async DoRun(runCount=0, maxCount=undefined) {
while (maxCount === undefined || runCount < maxCount) {
this.count += 1;
runCount += 1;
console.log(`total run count: ${this.count}`);
let taskList;
try {
this.active = true;
taskList = await Task.find({}).populate('relatedTasks').populate('notBefore');
//taskList = await this.makeload();
} catch (err) {
console.error(err);
this.active = false;
return;
}
}
}
即使在分配了90MB堆的情况下,即使在20000次调用之后,它仍然可以正常运行(到目前为止)。
在第一种情况下,我做错了什么?这让我相信sails有内存泄漏?或者节点无法释放数据库连接
我似乎看不到任何明显“泄漏”的东西?正如我在日志中看到的那样,this.count
不是一个字符串,因此它甚至没有泄漏(与runCount相同)
我如何才能从这一点上取得进展
编辑 进一步澄清/总结:
- 我在节点8.9.0上运行
- Sails版本1.0
- 使用sails postgresql适配器(1.0.0-12)(测试版和其他版本不适用于sails 1.0)
--max old space size=100
环境变量:
node\u env=production
在生产环境中运行约2000-2500次后(在调试模式下为500次),它会崩溃
我创建了一个github存储库,其中包含一个可行的代码示例;
. 再次在任何一点“很快”查看代码设置标志
--max old space size=80
(或类似的东西)我对sailsJS一无所知,但我可以回答标题中问题的前半部分:
V8/Node是否在函数调用期间进行垃圾收集
是的,绝对是。细节是复杂的(大多数垃圾收集工作是在小的增量块中完成的,并且尽可能在后台完成),并且随着垃圾收集器的改进而不断变化。其中一个基本原则是,分配会触发大量GC工作
垃圾收集器不关心函数调用或事件循环。我对sailsJS一无所知,但我可以回答标题中问题的前半部分: V8/Node是否在函数调用期间进行垃圾收集 是的,绝对是。细节是复杂的(大多数垃圾收集工作是在小的增量块中完成的,并且尽可能在后台完成),并且随着垃圾收集器的改进而不断变化。其中一个基本原则是,分配会触发大量GC工作
垃圾回收器不关心函数调用或事件循环。我不确定是否可以提供帮助,但如果有人这样做,他们需要知道您正在运行的sails版本(0.12.x或1.0)以及您正在使用的db适配器。@lascort感谢您通知我这个遗漏的信息-我更新了它。您是否在没有
.populate
调用的情况下进行了测试?如果省略该选项后运行良好,则可以确定问题在吃水线范围内。@arbuthnott如果没有填充调用,则错误发生的时间要晚得多-大约需要2-3倍的调用次数。-但是,由于内存泄漏,节点仍将崩溃。我不确定是否可以对此提供帮助,但如果有人这样做,他们将需要知道您正在运行的sails版本(0.12.x或1.0)以及您正在使用的db适配器。@lascort感谢您通知我这一遗漏的信息-我更新了它。您是否在没有.populate
调用的情况下进行了测试?如果省略该选项后运行良好,则可以确定问题在吃水线范围内。@arbuthnott如果没有填充调用,则错误发生的时间要晚得多-大约需要2-3倍的调用次数。-但是,节点仍将由于内存泄漏而崩溃。因此,这意味着错误(内存不足)始终是泄漏的结果(或者只是试图积累大量内存)这并不是因为“收集器没有时间运行”。正确,垃圾收集器将始终运行(并且只需花费它所需的任何时间),您无法(有意或无意)停止它。因此,这意味着错误(内存不足)始终是泄漏的结果(或者只是试图积累一大块内存)。-并不是因为“收集器没有时间运行”。正确,垃圾收集器将始终运行(并且只需要花费它所需要的任何时间),您无法停止它(有意或无意)。
async makeload() {
const promise = new Promise(resolve => {
setTimeout(resolve, 10, this);
});
await promise;
const ret = [];
for (let i = 0; i < 10000; i++) {
ret.push({
relatedTasks: [],
notBefore: [],
id: 1,
orderId: 1,
queueStatus: 'new',
jobType: 'test',
result: 'success',
argData: 'test',
detail: 'blah',
lastActive: new Date(),
updatedAt: Date.now(),
priority: 2 });
}
return ret;
}