我得到以下警告:

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace: 
    at EventEmitter.<anonymous> (events.js:139:15)
    at EventEmitter.<anonymous> (node.js:385:29)
    at Server.<anonymous> (server.js:20:17)
    at Server.emit (events.js:70:17)
    at HTTPParser.onIncoming (http.js:1514:12)
    at HTTPParser.onHeadersComplete (http.js:102:31)
    at Socket.ondata (http.js:1410:22)
    at TCP.onread (net.js:354:27)

我在server.js中写了这样的代码:

http.createServer(
    function (req, res) { ... }).listen(3013);

如何解决这个问题?


这在节点eventEmitter文档中有解释

这是什么版本的Node ?你还有其他代码吗?这不是正常的行为。

简而言之,它:process.setMaxListeners(0);

另见:node.js - request -如何“emitter.setMaxListeners()”?


将.on()替换为once()。使用once()在同一函数处理事件时删除事件监听器。

如果这不能解决问题,那么在package.json中重新安装restler :“restler git: / / github.com/danwrong/restler.git # 9 d455ff14c57ddbe263dbbcd0289d76413bfe07d”

这与restler 0.10对node的错误行为有关。你可以在这里看到git关闭的问题:https://github.com/danwrong/restler/issues/112 然而,npm还没有更新这个,所以这就是为什么你必须引用git头。


缺省情况下,任何单个事件最多可以注册10个侦听器。

如果这是你的代码,你可以通过:

const emitter = new EventEmitter()
emitter.setMaxListeners(100)
// or 0 to turn off the limit
emitter.setMaxListeners(0)

但如果这不是你的代码,你可以使用技巧来增加全局默认限制:

require('events').EventEmitter.prototype._maxListeners = 100;

当然,你可以关闭限制,但要小心:

// turn off limits by default (BE CAREFUL)
require('events').EventEmitter.prototype._maxListeners = 0;

顺便说一句。代码应该在应用程序的最开始。

ADD:从节点0.11开始,这段代码也可以改变默认限制:

require('events').EventEmitter.defaultMaxListeners = 0

我想在这里指出,这个警告是有原因的,正确的解决方法很可能不是增加限制,而是弄清楚为什么要向同一个事件添加如此多的侦听器。只有当您知道为什么要添加这么多侦听器并且确信这是您真正想要的时候,才增加限制。

我找到了这个页面,因为我得到了这个警告,在我的情况下,我正在使用的一些代码中有一个错误,将全局对象转换为EventEmitter!我当然不建议在全球范围内增加限制,因为你不想让这些事情被忽视。


把它放在你的server.js(或任何包含你的主Node.js应用程序)的第一行:

需要.EventEmitter.prototype(“事件”)。_maxListeners = 0;

错误就消失了:)


You said you are using process.on('uncaughtException', callback); Where are you executing this statement? Is it within the callback passed to http.createServer?If yes, different copy of the same callback will get attached to the uncaughtException event upon each new request, because the function (req, res) { ... } gets executed everytime a new request comes in and so will the statement process.on('uncaughtException', callback);Note that the process object is global to all your requests and adding listeners to its event everytime a new request comes in will not make any sense. You might not want such kind of behaviour. In case you want to attach a new listener for each new request, you should remove all previous listeners attached to the event as they no longer would be required using: process.removeAllListeners('uncaughtException');


当我在mac osx上安装aglio时,我也得到了这个警告。

我使用cmd修复它。

sudo npm install -g npm@next

https://github.com/npm/npm/issues/13806


在我的例子中,它是child.stderr.pipe(process.stderr),当我启动10个(或左右)child实例时,它被调用。因此,任何导致在LOOP中将事件处理程序附加到同一个EventEmitter对象的事情都会导致nodejs抛出这个错误。


有时,这些警告发生在我们没有做过的事情,而是我们忘记做的事情!

当我用npm安装dotenv包时遇到了这个警告,但在我在应用程序开始添加require('dotenv').load()语句之前就被打断了。当我回到项目时,我开始得到“可能的EventEmitter内存泄漏检测到”警告。

我以为问题出在我做了什么,而不是我没做什么!

一旦我发现了我的疏忽并添加了require语句,内存泄漏警告就清除了。


我们团队对此的解决方案是从.npmrc中删除注册表路径。rc文件中有两个路径别名,其中一个指向已弃用的Artifactory实例。

这个错误与我们的应用程序的实际代码无关,而是与我们的开发环境有关。


直到今天我开始监视咕噜咕噜的时候,我才开始这样做。最终由

watch: {
  options: {
    maxListeners: 99,
    livereload: true
  },
}

烦人的信息消失了。


公认的答案提供了如何增加限制的语义,但正如@voltrevo指出的那样,警告是有原因的,您的代码可能存在错误。

考虑以下有bug的代码:

//Assume Logger is a module that emits errors
var Logger = require('./Logger.js');

for (var i = 0; i < 11; i++) {
    //BUG: This will cause the warning
    //As the event listener is added in a loop
    Logger.on('error', function (err) {
        console.log('error writing log: ' + err)
    });

    Logger.writeLog('Hello');
}

现在观察添加监听器的正确方法:

//Good: event listener is not in a loop
Logger.on('error', function (err) {
    console.log('error writing log: ' + err)
});

for (var i = 0; i < 11; i++) {
    Logger.writeLog('Hello');
}

在更改maxListeners之前搜索代码中的类似问题(在其他答案中有解释)


我也有同样的问题。这个问题是因为我在两个监听器上监听端口8080。

setMaxListeners()工作得很好,但我不推荐它。

正确的方法是,检查你的代码额外的监听器,删除监听器或改变端口号,你正在监听,这解决了我的问题。


I prefer to hunt down and fix problems instead of suppressing logs whenever possible. After a couple days of observing this issue in my app, I realized I was setting listeners on the req.socket in an Express middleware to catch socket io errors that kept popping up. At some point, I learned that that was not necessary, but I kept the listeners around anyway. I just removed them and the error you are experiencing went away. I verified it was the cause by running requests to my server with and without the following middleware:

socketEventsHandler(req, res, next) {
        req.socket.on("error", function(err) {
            console.error('------REQ ERROR')
            console.error(err.stack)
        });
        res.socket.on("error", function(err) {
            console.error('------RES ERROR')
            console.error(err.stack)
        });
        next();
    }

删除该中间件将停止您所看到的警告。我会查看您的代码,并尝试找到您可能设置了不需要的侦听器的任何地方。


在创建新的侦听器之前,您需要使用以下命令清除所有侦听器:

客户端/服务器

socket.removeAllListeners(); 

假设socket是您的客户端套接字/或创建的服务器套接字。

你也可以订阅特定的事件监听器,比如像这样删除连接监听器:

this.socket.removeAllListeners("connect");

节点版本号:v11.10.1

来自堆栈跟踪的警告消息:

process.on('warning', e => console.warn(e.stack));
(node:17905) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 wakeup listeners added. Use emitter.setMaxListeners() to increase limit
MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 wakeup listeners added. Use emitter.setMaxListeners() to increase limit
    at _addListener (events.js:255:17)
    at Connection.addListener (events.js:271:10)
    at Connection.Readable.on (_stream_readable.js:826:35)
    at Connection.once (events.js:300:8)
    at Connection._send (/var/www/html/fleet-node-api/node_modules/http2/lib/protocol/connection.js:355:10)
    at processImmediate (timers.js:637:19)
    at process.topLevelDomainCallback (domain.js:126:23)

在搜索github问题,文档和创建类似的事件发射器内存泄漏后,由于node-apn模块用于iOS推送通知,观察到此问题。

这就解决了问题:

您应该为每个进程只创建一个Provider 您拥有的证书/密钥对。您不需要创建一个新的 每个通知的提供者。如果你只是发送通知 一个应用程序,那么就不需要一个以上的提供商。 如果你经常在你的应用程序中创建Provider实例,make 当你使用完每个提供者时,一定要调用provider .shutdown() 释放其资源和内存。

每次发送通知时,我都在创建提供者对象,并期望gc将其清除。


我也面临着同样的问题,但我已经成功地处理了异步等待。 请检查是否有帮助。 let dataLength = 25; 之前: for(设I = 0;i < dataLength;我+ +){ sftp。get (remotePath fs.createWriteStream (xyzProject / ${数据[我]. name})); } 后: for(设I = 0;i < dataLength;我+ +){ 等待sftp。get (remotePath fs.createWriteStream (xyzProject / ${数据[我]. name})); }


感谢RLaaa给了我一个如何解决警告的真正问题/根本原因的想法。在我的例子中,是MySQL有bug的代码。

假设你写了一个承诺,里面的代码是这样的:

pool.getConnection((err, conn) => {

  if(err) reject(err)

  const q = 'SELECT * from `a_table`'

  conn.query(q, [], (err, rows) => {

    conn.release()

    if(err) reject(err)

    // do something
  })

  conn.on('error', (err) => {

     reject(err)
  })
})

注意,代码中有一个conn.on('error')侦听器。代码一遍又一遍地添加监听器取决于调用查询的次数。 同时if(err) reject(err)做同样的事情。

所以我删除了conn.on('error')监听器,瞧…解决了! 希望这对你有所帮助。


正如其他人所指出的那样,提高限额并不是最好的答案。我也面临着同样的问题,但在我的代码中,我没有使用任何事件侦听器。当我仔细研究代码时,我有时会创建很多承诺。每个承诺都有一些抓取所提供URL的代码(使用一些第三方库)。如果你正在做类似的事情,那么它可能是原因。

在使用ES6的Promise.all()时,限制并发性的最佳方法是什么?


在我的情况下,这是由于没有关闭到数据库的Sequelize连接,而创建他们内部的异步函数调用setInterval。


添加EventEmitter.defaultMaxListeners = <MaxNumberOfClients>到node_modules\loop -datasource-juggler\lib\datasource.js修复了可能的问题:)