我正在尝试将数据之间同步到数据存储,源是mssql,目标是MongoDB。在此同步过程中,我遇到了内存堆错误。我不确定为什么会发生这种情况,我完全知道以下代码可能不是最好的,但是现在我只是想了解为什么分配错误会出现。
我正在用babel编译我的代码,在开发中我只使用babel-node。
try {
const response = await sqlDataStore.findAll({
attributes: ['id', 'Name'],
});
/* eslint no-restricted-syntax: 0 */
for (const item of response) {
/* eslint no-await-in-loop: 0 */
await this.Model.updateOne({}, item, { upsert: true });
}
} catch (err) {
console.log(err);
}
如果我正确理解堆错误是由for循环引起的,那么这意味着每个await语句都缓存在内存中。我本来希望从内存中清除每个await语句,因为我没有将其分配给任何变量。
已更新:
很高兴由于另一则帖子,我已经找到了解决方案:Bulk upsert in MongoDB using mongoose
我的代码:
const response = await sqlDataStore.findAll({
attributes: ['id', 'Name'],
});
const bulkUpdate = response.map(doc => ({
updateOne: {
filter: { _id: doc.id },
update: doc.dataValues,
upsert: true,
},
}));
this.Model.collection.bulkWrite(bulkUpdate);
如果有人正在使用此解决方案,则应记住,这也可能导致大量数据崩溃。其他职位提供的解决方案建议应在1000个存储桶中处理数据,直到每个文档都被更新/插入。
仅出于兴趣和技术上的理解,我将对我在第一个代码中确实做错了什么进行解释。
答案 0 :(得分:0)
之所以得到这个,是因为您的函数调用堆栈没有释放,因为他们正在等待其他调用来完成其执行。
由于所有调用堆栈都阻塞了您的堆栈内存,因此在执行某些代码后,您将出现内存不足异常。
检查此链接: https://eslint.org/docs/rules/no-await-in-loop
您可以看到您的await呼叫在内存中被阻塞,以等待其他await完成,并且他们正在一次性向您返回值,这在您的代码中很糟糕。
实际上您是在进行同步通话,每个同步通话都在等待其他同步通话结束,最后,您的同步通话堆积在堆栈内存中,并且您遇到异常