【问题标题】:how to handle crashes assocaiated with memory allocation in nodejs?如何处理与节点 js 中的内存分配相关的危机?
【发布时间】:2026-01-28 19:35:01
【问题描述】:

我正在尝试用来自 faker 的一些随机数据填充 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】:

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

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

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

    更细微的方法是通过使用计数器来限制并发 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);
    

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

    【讨论】:

    • 谢谢@David784 是的,对 setInterval 的实际工作方式存在误解