如果未调用removeAllListeners(),EventEmitter会导致内存泄漏吗?

时间:2013-04-28 22:19:09

标签: node.js eventemitter

当我使用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();
  }
);

如图所示,从不删除侦听器。如果进程在运行一次后立即退出,这可能没问题。但是,如果进程长时间运行,代码会重复执行,是否会导致内存泄漏?即由于侦听器永远不会被删除,因此它们会保留所有获取和消息对象,即使它们仅用于命令的持续时间。

我的理解不正确吗?

1 个答案:

答案 0 :(得分:1)

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

你似乎认为听众会将事件发射器保持在周围,但事实恰恰相反。

您提供的示例很可能不会导致内存泄漏,因为看起来像msg在它完成之后由node-imap处理。