【问题标题】:Would EventEmitter cause memory leak if removeAllListeners() is not called?如果不调用 removeAllListeners(),EventEmitter 会导致内存泄漏吗?
【发布时间】:2013-04-28 22:19:08
【问题描述】:

当我使用 node-imap 模块时,我想到了这个问题。 (见https://github.com/mscdex/node-imap

在此模块中,fetch() 方法将调用一个回调函数,该函数为它提供一个 ImapFetch() 对象,假设您的代码监听“消息”事件。消息事件依次为每个对象传递一个消息对象,其中包含您需要监听的事件。

这是模块中的示例代码:

imap.fetch(results,
  { headers: ['from', 'to', 'subject', 'date'],
    cb: function(fetch) {
      fetch.on('message', function(msg) {
        console.log('Saw message no. ' + msg.seqno);
        msg.on('headers', function(hdrs) {
          console.log('Headers for no. ' + msg.seqno + ': ' + show(hdrs));
        });
        msg.on('end', function() {
          console.log('Finished message no. ' + msg.seqno);
        });
      });
    }
  }, function(err) {
    if (err) throw err;
    console.log('Done fetching all messages!');
    imap.logout();
  }
);

如图所示,监听器永远不会被移除。如果进程在运行一次后立即退出,这可能会很好。但是,如果进程长时间运行,代码会重复执行,会不会导致内存泄漏? IE。由于侦听器永远不会被移除,因此它们保留所有 fetch 和 message 对象,即使它们仅在命令期间使用。

我的理解有误吗?

【问题讨论】:

    标签: node.js eventemitter


    【解决方案1】:

    只要msg 保留在内存中,您的每个听众都会保留在内存中。如果msg 的寿命比您预期的长,这可能会导致内存泄漏,例如仍然从某个地方引用。但是,如果没有更多对 msg 的引用,那么它将从内存中删除,如果没有更多对它们的引用,侦听器将跟随。

    您似乎认为侦听器会保留事件发射器,但事实恰恰相反。

    您给出的示例很可能不会导致内存泄漏,因为它看起来像 msg 在它完成后被 node-imap 释放。

    【讨论】:

    • 你是对的。我错误地认为事件侦听器可能会添加对 msg 的额外引用,但实际上并没有发生。
    猜你喜欢
    • 2022-06-13
    • 2019-02-03
    • 2021-03-23
    • 2021-09-25
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    相关资源
    最近更新 更多