检测到可能的EventEmitter内存泄漏
我收到以下警告:
(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);
如何解决这个问题?
这在手册中有解释: http : //nodejs.org/docs/latest/api/events.html#events_emitter_setmaxlisteners_n
这是什么版本的节点? 你有什么其他的代码? 这不是正常的行为。
简而言之,它的: process.setMaxListeners(0);
另请参阅: node.js – 请求 – 如何“emitter.setMaxListeners()”?
我想在这里指出,这个警告是有原因的,有一个很好的机会,正确的解决scheme并没有增加限制,但搞清楚为什么你join这么多听众的同一事件。 如果你知道为什么要join这么多的听众,只有增加限制,并且确信这就是你真正想要的。
我发现这个页面,因为我得到了这个警告,在我的情况下,我正在使用的一些代码中有一个错误,将全局对象变成EventEmitter! 我当然会build议不要在全球范围内增加限制,因为你不希望这些东西被忽视。
默认情况下,任何单个事件最多可以注册10个监听器。如果是您的代码,您可以通过以下方式指定maxListeners:
const emitter = new EventEmitter() emitter.setMaxListeners(100) // or 0 to turn off the limit emitter.setMaxListeners(0)
但是,如果这不是你的代码,你可以使用这个技巧来增加全局的默认限制:
require('events').EventEmitter.prototype._maxListeners = 100;
当然,您可以closures限制,但要小心:
// turn off limits by default (BE CAREFUL) require('events').EventEmitter.prototype._maxListeners = 0;
PS。 代码应该在你的应用程序的开始。
ADD:由于节点0.11,这也适用于更改默认限制:
require('events').EventEmitter.defaultMaxListeners = 0
用once()replace.on()。 使用once()可以在事件由同一个函数处理时删除事件侦听器。 来源: http : //nodeguide.com/beginner.html#using-eventemitters
如果这不能解决它,然后重新安装与你的package.json restler“restler”:“git://github.com/danwrong/restler.git#9d455ff14c57ddbe263dbbcd0289d76413bfe07d”
这与restler 0.10与节点行为不当有关。 你可以看到这个问题在git上closures: https : //github.com/danwrong/restler/issues/112然而,npm还没有更新,所以你必须参考git头。
快乐的rest:)
接受的答案提供了如何增加限制的语义,但是@voltrevo指出,警告是有原因的,您的代码可能有一个错误。
考虑以下错误代码:
//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'); }
现在观察添加监听器的正确方法:
Logger.on('error', function (err) { console.log('error writing log: ' + err) }); for (var i = 0; i < 11; i++) { //Good: event listener is not in a loop Logger.writeLog('Hello'); }
在更改maxListeners之前,在您的代码中search类似的问题(在其他naswers中进行了解释)
在我的mac osx上安装aglio时,我也收到了这个警告。
我用cmd修复它。
sudo npm install -g npm@next
在我的情况下,它是child.stderr.pipe(process.stderr)
,当我发起孩子的10个(或多个)实例时被调用。 因此,任何导致将事件处理程序附加到LOOP中的相同EventEmitter对象的操作都会导致nodejs抛出此错误。
有时候这些警告是在我们所做的事情不是这样的时候发生的,而是我们忘记做的事情!
当我用npm安装了dotenv软件包时遇到了这个警告,但是在我开始添加require('dotenv')。load()语句之前被打断了。 当我回到项目时,我开始得到“可能的EventEmitter内存泄漏检测”警告。
我认为问题来自于我所做的事情,而不是我没做过的事情!
一旦我发现我的疏忽,并添加了要求声明,清除内存泄漏警告。
当我开始grunt watch
时候,直到今天,我一直在这里。 终于解决了
watch:{ options:{ maxListeners: 99, livereload: true }, }
烦人的消息不见了
你说你正在使用process.on('uncaughtException', callback);
你在哪里执行这个声明? 它是否在传递给http.createServer
的callback中?
如果是的话,每次新的请求时,同一callback的不同副本将被附加到uncaughtException事件上,因为每次有新的请求进入时, function (req, res) { ... }
都会被执行,语句process.on('uncaughtException', callback);
请注意, 过程对象对于所有请求都是全局的 ,并且每当有新的请求进来时,都会将侦听器添加到其事件中,这是没有任何意义的。 你可能不想要这样的行为。
如果你想为每个新的请求附加一个新的监听器,你应该删除所有以前的监听器,因为它们不再需要使用:
process.removeAllListeners('uncaughtException');
我们团队的解决方法是从我们的.npmrc中删除registrypath。 我们在rc文件中有两个path别名,一个指向已经被弃用的Artifactory实例。
该错误与我们的应用程序的实际代码无关,但与我们的开发环境有关。
把这个放在server.js的第一行(或者包含你的主Node.js应用程序的东西):
require('events').EventEmitter.prototype._maxListeners = 0;
和错误消失:)