我正在尝试用来自造假者的一些随机数据填充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);
});
});
我应该如何管理内存分配以防止崩溃?被认为是内存泄漏吗?
没有时间调用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
使用零。