2013-03-23 78 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(); 
    }); 
}