【问题标题】:JavaScript heap out of memory while updating the mongodb更新 mongodb 时 JavaScript 堆内存不足
【发布时间】: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行。
  • 嗨,我知道操作被延迟了,但这不是我的问题,问题是它们是否确实存储在内存中,以及即使我没有将响应存储在任何内容中,这是否是预期的行为变量。
  • 我猜这是因为您的执行完全阻塞了下一次执行,并且将在内存中直到您的整个执行完成。检查我分享的链接。

标签: node.js mongodb mongoose sequelize.js


【解决方案1】:

你得到这个是因为你的函数调用堆栈没有得到空闲,因为它们正在等待其他调用完成它的执行。

由于所有调用堆栈都阻塞了您的堆栈内存,因此在执行一些操作后您将遇到内存不足异常。

检查此链接: https://eslint.org/docs/rules/no-await-in-loop

如您所见,您的 await 调用在内存中被阻塞,等待其他 await 完成,他们一次性返回您的值,这对您的代码不利。

实际上是您正在进行同步调用,并且每个同步调用都在等待其他同步调用完成,最后,您的同步调用堆积在堆栈内存中并且您遇到了异常 .

【讨论】:

    猜你喜欢
    • 2019-05-27
    • 2018-02-10
    • 2019-09-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 2017-10-10
    • 2019-09-10
    • 1970-01-01
    相关资源
    最近更新 更多