如何处理与Node.js中的内存分配相关的崩溃?

问题描述 投票:0回答:1

我正在尝试用来自造假者的一些随机数据填充mongoDB数据库。所以我使用setInterval函数来运行数据库查询,但是问题是当我监视内存使用时,它会不断增长,直到达到v8引擎的极限,无论我增加了多少崩溃极限无论如何只是时间问题。

const faker = require("faker")
let userName; 
let email; 

setInterval(async () => {
  userName = faker.name.findName(); 
  email = faker.internet.email(); 
  await User.create({
    userName: userName,
    email: email,
  })
    .then(() => {
      //getting memory usage
      console.log(process.memoryUsage().heapUsed / 1024 / 1024);
    })
    .catch(err => {
      console.log(err);
    });
});

我应该如何管理内存分配以防止崩溃?被认为是内存泄漏吗?

javascript node.js memory-management memory-leaks setinterval
1个回答
0
投票

没有时间调用setInterval,这将尽可能快地添加到回调队列中,而没有任何限制。而且,如果将项目添加到队列中的速度比删除它们的速度快,则内存将始终增长。

*编辑:要确切了解在执行setInterval时事件循环和回调队列会发生什么,我建议观看Philip Roberts和/或Jake Archibald进行的出色的JSConf演讲。

您有几种选择。您可以更改为setTimeout,然后在最后一次调用完成后在setTimeout中调用另一个.then。这实际上将序列化它。

更细微的方法是通过使用计数器来限制并发mongoDB写入的最大数量。这样,您可以同时进行一定数量的写入。在此示例中,它将并发写入数限制为10。这应使您的内存不受限制地增长。

const faker = require("faker")
let userName; 
let email; 
let numRunning = 0;
let maxRunning = 10;

setInterval(async () => {
  if (numRunning > maxRunning) return;
  numRunning++;
  userName = faker.name.findName(); 
  email = faker.internet.email(); 
  await User.create({
    userName: createdUser.userName,
    age: createdUser.age,
  })
    .then(() => {
      numRunning--;
      //getting memory usage
      console.log(process.memoryUsage().heapUsed / 1024 / 1024);
    })
    .catch(err => {
      numRunning--;
      console.log(err);
    });
}, 50);

我还添加了50ms的间隔。 setInterval的零实际上不是一个好主意。有充分的理由有时为setTimeout使用零,但我想不出有充分的理由为setInterval使用零。

© www.soinside.com 2019 - 2024. All rights reserved.