简体   繁体   English

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

[英]how to handle crashes assocaiated with memory allocation in nodejs?

I am trying to fill mongoDB database with some random data from faker.我正在尝试用来自 faker 的一些随机数据填充 mongoDB 数据库。 So i used setInterval function to run a database Query over and over its working but the problem is when i monitor my memory usage it just growing and growing until it reaches to the that limit of v8 engine no matter how much i increase the limits it crashes anyway just a matter of time.所以我使用 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);
    });
});

how should i manage memory allocation to stop crashes?我应该如何管理内存分配以阻止崩溃? is this considered to be a memory leak?这被认为是内存泄漏吗?

Calling setInterval with no time, this is adding to the callback queue as fast as possible, without any limits.没有时间调用setInterval ,这是尽可能快地添加到回调队列中,没有任何限制。 And if you add items to a queue faster than you can remove them, memory will always grow.如果您将项目添加到队列的速度比删除它们的速度快,则内存将始终增长。

*Edit: to understand exactly what happens with the event loop and callback queue when you do a setInterval , I recommend watching the excellent JSConf talks by Philip Roberts and/or Jake Archibald . *编辑:要准确了解执行setInterval时事件循环和回调队列会发生什么,我建议观看Philip Roberts和/或Jake Archibald出色的 JSConf 演讲。

You have a few options.你有几个选择。 You could change to a setTimeout , and then invoke another setTimeout in your .then , once the last call has finished.你可以更改为setTimeout ,然后调用其他setTimeout在你的.then ,一旦最后一次通话结束。 This would essentially serialize it.这基本上会将它序列化。

A more nuanced approach would be to limit the max number of concurrent mongoDB writes by using a counter.更细致的方法是使用计数器限制并发 mongoDB 写入的最大数量。 That way you can have a certain number of writes happening concurrently.这样你就可以同时进行一定数量的写入。 In this example, it limits the number of concurrent writes to 10. This should keep your memory from growing without limits.在此示例中,它将并发写入的数量限制为 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);

I also added an interval of 50ms.我还添加了 50ms 的间隔。 A zero for a setInterval really isn't a good idea. setInterval的零真的不是一个好主意。 There are good reasons to sometimes use a zero for setTimeout , but I can't think of a good reason to ever use a zero for a setInterval .有时对setTimeout使用零是有充分理由的,但我想不出对setInterval使用零的充分理由。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM