更新 mongodb 时 JavaScript 堆内存不足
Posted
技术标签:
【中文标题】更新 mongodb 时 JavaScript 堆内存不足【英文标题】:JavaScript heap out of memory while updating the mongodb 【发布时间】:2019-09-21 15:20:52 【问题描述】:我正在尝试在数据存储之间同步数据,源是 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 个桶中处理数据。
仅出于兴趣和技术理解,我希望能解释一下我在第一个代码中到底做错了什么。
【问题讨论】:
只是为了确定,代码在第一个 SQL 查询中运行良好吗?也就是说,是不是引入的数据量太大了? 是的,sql查询绝对没问题,数据量也不大,只有2401行。 查看这个eslint.org/docs/rules/no-await-in-loop 嗨,我知道操作被延迟了,但这不是我的问题,问题是它们是否确实存储在内存中,以及即使我没有将响应存储在任何内容中,这是否是预期的行为变量。 我猜这是因为您的执行完全阻塞了下一次执行,并且将在内存中直到您的整个执行完成。检查我分享的链接。 【参考方案1】:你得到这个是因为你的函数调用堆栈没有得到空闲,因为它们正在等待其他调用完成它的执行。
由于所有调用堆栈都阻塞了您的堆栈内存,因此在执行一些操作后您将遇到内存不足异常。
检查此链接: https://eslint.org/docs/rules/no-await-in-loop
如您所见,您的 await 调用在内存中被阻塞,等待其他 await 完成,他们一次性返回您的值,这对您的代码不利。
实际上是您正在进行同步调用,并且每个同步调用都在等待其他同步调用完成,最后,您的同步调用堆积在堆栈内存中并且您遇到了异常 .
【讨论】:
以上是关于更新 mongodb 时 JavaScript 堆内存不足的主要内容,如果未能解决你的问题,请参考以下文章
javascript 具有另一个字段值的mongodb更新字段