Node.js承诺设计中发生内存泄漏? [英] Memory leak in nodejs promise design?

查看:110
本文介绍了Node.js承诺设计中发生内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到这里有些人建议您使用await/async并在希望延迟执行某些操作时直接使用promise而不是setTimeout.这是代码:

I noticed some people here recommend to use await/async and promise instead of setTimeout directly when you want to delay the execution of something. This is the code:

async wait (ms){
  return new Promise(resolve => setTimeout(resolve, ms));
}

所以我会用

await wait(3000);
my_function();

代替

setTimeout(() => {
  my_function();
}, 3000);

这是有道理的,但我注意到,如果这样做,则会增加内存使用率,并最终在几个小时后由于内存不足而使应用程序崩溃.

It makes sense but I noticed that if I do that I get increased memory usage and eventually the app crashes with heap of out memory after a few hours.

这是nodejs的promise设计中的问题,还是我在这里遗漏了什么?

Is this an issue in the promise design of nodejs, or am I missing something here?

此代码重现了该问题:

const heapdump = require('heapdump'),
      fs = require('fs');
class test {
  constructor(){
    this.repeatFunc();
  }
  async wait (ms){
    return new Promise(resolve => setTimeout(resolve, ms));
  }
  async repeatFunc(){ 
    // do some work...
    heapdump.writeSnapshot(__dirname + '/' + Date.now() + '.heapsnapshot');    

    await this.wait(5000); 
    await this.repeatFunc();
  }
}
new test();

通知堆转储每5秒不断增加

Notice heap dump keeps increasing every 5 seconds

使用setInterval不会发生这种情况:

With setInterval this doesn't happen:

const heapdump = require('heapdump'),
      fs = require('fs');
class test {
  constructor() {
    setInterval(this.repeatFunc, 5000);
  }
  repeatFunc() { 
    // do some work...
    heapdump.writeSnapshot(__dirname + '/' + Date.now() + '.heapsnapshot');    
  }
}
new test();

推荐答案

您已经编写了一个无限递归函数,每个函数调用都返回一个新的Promise.每个诺言都在等待从内部诺言中解决-是的,它当然是在累积内存.如果代码是同步的,那么您将获得堆栈溢出异常.

You have written an infinitely recursive function, and each function call returns a new promise. Each promise is waiting to be resolved from the inner one - so yes, it of course is accumulating memory. If the code was synchronous, you would have gotten a stack overflow exception instead.

只需使用循环即可:

const heapdump = require('heapdump'),
      fs = require('fs');

async function wait(ms){
  return new Promise(resolve => setTimeout(resolve, ms));
}
async function repeat() {
  while (true) {
    // do some work...
    heapdump.writeSnapshot(__dirname + '/' + Date.now() + '.heapsnapshot');    

    await wait(5000); 
  }
}

repeat().then(() => console.log("all done"), console.error);


我注意到这里有些人建议使用await/async并承诺当您要延迟执行某些操作时直接使用setTimeout.

I noticed some people here recommend to use await/async and promise instead of setTimeout directly when you want to delay the execution of something.

包括我在内,因为promise易于使用,尤其是当您要从异步任务返回结果值或处理错误时.但是,如果您对promise的优点不满意,那么没有什么可以迫使您将已经工作的代码转换为promise.只需继续使用回调样式,直到找到对Promise有用的地方即可.

Well that includes me, as promises are much easier to work with, especially when you want to return a result value from your asynchronous task or handle errors. But if you're not convinced by any of the advantages of promises, there is nothing that forces you convert your already-working code to promises. Just carry on using callback style until you find a good use for promises.

这篇关于Node.js承诺设计中发生内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆