2013-03-23 23 views
47

如何调试我的应用程序,它抛出这个错误:的NodeJS:如何调试“EventEmitter内存泄漏检测11个听众补充。”

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. 
Trace 
    at Socket.EventEmitter.addListener (events.js:160:15) 
    at Socket.Readable.on (_stream_readable.js:653:33) 
    at Socket.EventEmitter.once (events.js:179:8) 
    at TCP.onread (net.js:527:26) 

我无法找到由.setMaxListeners(0);增加听众的限制假定泄漏对象

解决方案(从fardjad和Jan Salawa先生)

随着一月Salawa先生的搜索,我发现一个工作库(longjohn)增加堆栈跟踪冗长。随着fardjad的回应,我发现我们必须制作原型EventEmitter.addListenerANDEventEmitter.on

通过该解决方案,我可以得到这个新的跟踪:

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. 
Trace 
    at EventEmitter.addListener.EventEmitter.on (xxx/main.js:44:15) 
    at Readable.on (_stream_readable.js:653:33) 
    at ServerResponse.assignSocket (http.js:1072:10) 
    at parser.onIncoming (http.js:1979:11) 
    at parserOnHeadersComplete (http.js:119:23) 
    at socket.ondata (http.js:1912:22) 
    at TCP.onread (net.js:510:27) 
+0

查看关于agent.maxSockets http://weblog.bocoup.com/node-stress-test-analysis/的相关信息。也许这是一个原因。 – 2013-03-31 21:23:13

+0

尝试没有成功。我把'require(“http”)。globalAgent.maxSockets = Infinity;'放在我的main.js中,但没有任何变化...... :(我也尝试过'ulimit -n 999999'命令打开文件限制和'--nouse- idle-notification'用于暂停实时垃圾收集器... – Ifnot 2013-04-01 14:27:51

+0

这完全挂起了我的节点js服务器,当我按下control + C其他处理启动时,在本地运行时发生异常。我试过设置maxListeners没有用,它是什么说是我有太多的人连接到相同的听众,或者说我有太多的事件 – 2017-09-07 11:50:10

回答

28

事实证明,这是的NodeJS核心中的错误,我们在这里谈论这个问题:对bug的HTTP服务器,这就是

https://github.com/joyent/node/issues/5108

解决方案抛出EventEmitter memory leak detected并填补现有内存/可用CPU时间:

还原为旧版本v0.8.23

您可以下载并安装/从这里编译:

http://blog.nodejs.org/2013/04/08/node-v0-8-23-legacy/

+3

感谢您的更新:) – robertklep 2013-04-25 18:38:28

+0

^这! ....... – AlienWebguy 2013-04-25 23:01:45

+0

一旦他们明确解决了这个问题,我会尽量让每个人都发布在节点的更新工作版本上。我仍然遇到问题。 – marksyzm 2013-07-26 10:38:20

4

I tried to prototype the EventEmitter for adding log messages into addListener but i could not get it working

挂钩addListener你可以做这样的事情:

// on the first line of your main script 
var events = require("events"), 
    EventEmitter = events.EventEmitter; 

var originalAddListener = EventEmitter.prototype.addListener; 
EventEmitter.prototype.addListener = function (type, listener) { 
    if (this.listenerCount(this, type) >= 10) { 
     // TODO: PLACE YOUR CODE FOR DEBUGGING HERE 
    } 
    originalAddListener.apply(this, arguments); 
} 
+0

它不起作用。钩为一些我的应用程序监听器,但不是所有的监听器调用。不幸的是,'addListener'巫火这个错误不会执行钩子(我试图记录所有的解析器去除条件)。 这个钩子是否附加在模块'events.EventEmitter.addListener'上吗?(也许问题来自我使用的“坏”模块?) – Ifnot 2013-03-23 14:16:54

+0

这个问题可能是由坏模块引起的,但是'node.js'缓存模块。多次尝试“需要”模块(通常)加载模块一次。所以如果你在你的主脚本上安装钩子,其他模块应该使用挂钩的'addListener'。 – fardjad 2013-03-23 14:59:09

+0

你是对的,我试图把你的代码放在一些模块中,结果是一样的:我在应用程序开始时在不同的objets上有20/30位听众,当错误出现时没有任何东西:(。 – Ifnot 2013-03-23 15:13:07

11

对我来说这看起来像你的事件循环受阻。如果您在node.js事件循环中执行cpu密集型任务,可能会发生这种情况。您可以使用child process来完成强化任务。

您可以检查什么用following methods阻塞Node.js的:

  1. 每个呼叫的Measure computation time。如果时间很长,请记录日期,以便知道应用程序行为异常。
  2. ,所以你知道建立日志,日程安排时,东西挡住环
    function timeTick() { 
        var startTime = (new Date().getTime()); 
        function onTick() { 
         var interval = (new Date().getTime()) - startTime; 
         if(interval > 5) 
          console.log('timeTick(): WARNING: interval = ' + interval); 
        } 
        process.nextTick(onTick); 
    } 
    setInterval(timeTick, 1000);
  3. 使用profile.
  4. 使用this进行记录和分析。它的库用于Nodejitsu
+1

是的,这个问题来自一个对象,当密集型任务时添加了太多的监听器。但我必须找到女巫的对象,并增加听众的限制!问题是如何找到问题的来源? – Ifnot 2013-03-25 14:59:00

+0

我不确定你是否在做cpu密集型任务。我编辑了我的帖子。 – 2013-03-25 15:26:57

+0

当密集任务(处理多个连接)时,CPU不会超过一个内核的20%。但**之后的错误发生后,程序开始使用100%的CPU和不断增长的内存。 – Ifnot 2013-03-25 15:30:20

9

这正是发生在我身上。对我而言,我意外地在另一个事件监听器中嵌套了一个事件监听器。

看看你的代码,并确保你没有一个事件侦听器块内,例如另一个事件监听器模块(除非你是有意的):上述

socket.on('data', function(data) { 
//code goes here 

socket.on('close' , function() { 
//code goes here 
    }); 

    }); 

在错误的例子中, socket.on('close')监听器应该在socket.on('data')块的外面。

在我的情况下,当我收到5个数据流时,socket.on('close')侦听器正在等待关闭事件发生。当我关闭一次时,将执行另一个第四次关闭事件。这显然不是我想要的。这是由于Node.js的非阻塞性质。它'记住'由于回调函数而导致的事件。

+0

这也是我的错误的原因根!我有'''somereaderstream.on(“close”,function ){fstream.Reader({'path':basepath,'type':'Directory'})。on(“end”,function(){.....});});谢谢指出! '' – 2014-04-06 21:19:07

4

如果您为同一对象的特定事件注册超过11次,则会引发此警告。

检查您是否正在经常打电话的函数中调用particualr事件,这会导致多次注册一个事件。

This链接帮助我理解这一点。

+1

它应该是'超过10倍' – 2016-07-07 12:46:58

+0

谢谢,这有帮助!我有一个应用程序play()和stop()方法。当stop()被调用时,我有一个EventEmitter发送一个“停止信号”,这会杀死一个进程(视频播放器)。问题是如果我调用play()11次:这个过程似乎让所有玩家进程都被注册为开放状态(即使他们没有注册),所以我需要在启动新进程之前终止任何进程。 – aesede 2016-08-30 23:07:04

0

我测试阵营使用摩卡组件时遇到了同样的问题。

我完成测试后,通过明确地卸载组件,我能够解决我的问题。

问题是我在我的测试中多次挂载组件,然后添加了更多的监听器,直到监听器的数量达到11,并且我收到警告。

我通过添加rendered.unmount()行更改了我的测试代码。这为我解决了这个问题。

describe('<CircleArc />',() => { 

    it('renders', function() { 
     const rendered = mount(<CircleArc />); 
     assert.ok(rendered.find('path')); 
     rendered.unmount(); 
    }); 
}