【问题标题】:setTimeout memory leak in Node(Meteor)Node(Meteor)中的setTimeout内存泄漏
【发布时间】:2018-06-13 07:19:57
【问题描述】:

我在使用 setTimeout 时遇到了奇怪的内存泄漏。

我每 15 秒调用一次以下代码,并使用一个返回一组承诺 (Promise.all) 的异步函数,它应该在所有承诺解决并完成所有逻辑后再次运行 15 秒。

const schedule = (fn, seconds, runNow = false) => {
  Meteor.setTimeout(() => {
    try {          
      Promise.resolve(fn()).then(()=>{
        schedule(fn, seconds, false)
      }).catch((err)=>{
        log.error(err)
        schedule(fn, seconds, false)
      })
    } catch (e) {
      log.error(e);
    }
  }, runNow ? 0 : seconds * 1000);
};

我已经尝试了 setTimeout 和上面的 Meteor.setTimeout 并且它们的行为相同,大约一个小时后你可以看到明显的内存泄漏。

值得一提的是,即使我禁用了我的代码并且被调用的函数只是返回,它仍然会泄漏。

服务器:OSX、Node 9.3、Meteor 1.6

发现很少有其他人使用 setTimeout 发生内存泄漏,但情况不同。

更新 问题是调度函数正在另一个我不知道的任务中被调用,并且一个异步代码非常繁重并且缺少等待,所以它在完成之前被重新调度,一段时间后它加起来。谢谢大家的回答。

【问题讨论】:

    标签: javascript node.js meteor memory-leaks settimeout


    【解决方案1】:

    如果去掉 try catch 会发生什么?

    const schedule = (fn, seconds, runNow = false) => {
      Meteor.setTimeout(() => {
        Promise.resolve()
        .then(fn)
        .then(
          ()=>
            schedule(fn, seconds, false)
        )
        .catch((err)=>{
          log.error(err)
          schedule(fn, seconds, false)
        });
      }, runNow ? 0 : seconds * 1000);
    };
    

    我不确定你为什么要尝试并捕获,我假设 fn 是一个可以抛出错误并且不返回承诺的函数(如果它确实不会抛出并拒绝)。

    对于可以在承诺链中使用的函数,您只需将它们放在 承诺链中。 Promise.resolve(fn()) 不会将其放入链中,但 Promise.resolve().then(fn) 会。

    var fn = function(){throw("Not caught in promise")};
    
    var fn = function(){throw("Not caught in promise")};
    Promise.resolve().then(fn)
    .catch(e=>console.log("============ is caught"));
    
    Promise.resolve(fn())
    .catch(e=>console.log("not caught"));

    【讨论】:

    • 这不完全是问题,但它帮助我找出了真正的问题,即我不知道的呼叫中缺少等待。谢谢!
    【解决方案2】:

    我不确定这是否是解决方案,但在 ReactJS 常见问题解答中有一个名为 Arrow Function in Render 的主题:

    在渲染中使用箭头函数每次都会创建一个新函数 组件渲染,这可能会影响性能(见下文)。

    也许这里也是这种情况?

    值得一提的是,即使我禁用了我的代码并且被调用的函数只是返回,它仍然会泄漏。

    PS:也许你可以添加仍然泄漏的最小代码示例?

    【讨论】:

    • 渲染是在客户端完成的,所以即使那里的代码不好,也不应该影响服务器。
    猜你喜欢
    • 2013-04-10
    • 1970-01-01
    • 2021-01-25
    • 2021-01-31
    • 2014-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多