JavaScript heap out of memory while updating the mongodb
我正在尝试将数据之间同步到数据存储,源是mssql,目标是MongoDB。在此同步过程中,我遇到了内存堆错误。我不确定为什么会发生这种情况,并且我完全知道以下代码可能不是最好的,但是现在我只是想了解为什么分配错误会出现。
我正在用babel编译我的代码,在开发中我只使用babel-node。
1 2 3 4 5 6 7 8 9 10 11 12 | 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语句,因为我没有将其分配给任何变量。
已更新:
很高兴我已经找到了一个解决方案,这要归功于另一篇文章:使用mongoose在MongoDB中批量上传
我的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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个存储桶中处理数据,直到每个文档都被更新/插入。
仅出于兴趣和技术上的理解,我将对我在第一个代码中确实做错了什么进行解释。
之所以得到这个,是因为您的函数调用堆栈没有释放,因为他们正在等待其他调用以完成其执行。
由于所有调用堆栈都阻塞了您的堆栈内存,因此在执行某些代码后,您将出现内存不足异常。
检查此链接:
https://eslint.org/docs/rules/no-await-in-loop
您可以看到您的await呼叫在内存中被阻塞,以等待其他await完成,并且它们正在一次性返回您的值,这在您的代码中是很糟糕的。
实际上是您在进行同步通话,每个同步通话都在等待其他同步通话结束,最后,您的同步通话堆积在堆栈内存中,并且您遇到异常
。