NodeJS : How to debug “EventEmitter memory leak detected. 11 listeners added”

冷暖自知 提交于 2019-11-26 08:48:26

问题


How can I debug my application which throw this error:

(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)

I could not find the assumed leaking object for increasing listener limit by .setMaxListeners(0);

SOLUTION (from fardjad and jan salawa)

With jan salawa\'s searches I found a working library (longjohn) for increasing stack traces verbose. With fardjad\'s response I have found that we have to prototype EventEmitter.addListener AND EventEmitter.on.

With the solution I could get this new trace:

(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)

回答1:


It turns out that this is a bug in nodejs core, we are talking about this problem here : https://github.com/joyent/node/issues/5108

Solution for bugged http servers thats throw an EventEmitter memory leak detected and fill up the available memory / available CPU times :

Revert to legacy version v0.8.23. (You can download and install/compile it from here : http://blog.nodejs.org/2013/04/08/node-v0-8-23-legacy/)

UPDATE 2018 : I see several feedbacks on this topic whereas the problem looks to be gone since years. Note that this response is only for a leaking http server build with nodejs. If you are in other scenario, please look the others responses on this thread and dont downgrade your version (as suggested on this response), you will waste your time.




回答2:


For me it's looks like your event loop is blocked. This can happen if you are doing cpu intensive tasks in node.js event loop. You can use child process to do intensive task.

You can check what is blocking node.js using following methods:

  1. Measure computation time of each call. Log if time is high so you know app is misbehaving.
  2. Set up a log schedule so you know when something blocking loop
    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. Use profile.
  4. Use this for logging and profiling. It's library used in Nodejitsu.



回答3:


This is exactly what happened to me. For me, I nested an event listener within another event listener accidentally.

Look at your code and make sure you DO NOT have an event listener block WITHIN another event listener block for example(unless you are doing it on purpose):

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

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

   });

In the wrong example above, the socket.on ('close') listener should be OUTSIDE of the socket.on('data') block.

In my case when I received 5 data streams, the socket.on('close') listener is waiting for a close event to happen. When I close once, another 4th closing event would execute. This is clearly not what I wanted. This is due to the nature of Node.js which is non-blocking. It 'remembers' events due to the callback function.




回答4:


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

To hook addListener you can do something like this:

// 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);
}



回答5:


This warning will be thrown if you register for a particular event of a same object more than 11 times.

Check if you are having 'on' call for particualr event in a function which you are calling frequently, this leads to registering for an event multiple times.

This link helped me to understand this.




回答6:


Since node 6 you should use node --trace-warnings: https://nodejs.org/api/cli.html#cli_trace_warnings




回答7:


I was seeing this when I was running my unit tests. My unit tests were repeatedly calling code that was calling:

process.on("uncaughtException", () => { ... });

I had to use dependency injection to inject a fake process object, which solved the problem.

main.js:

export function main(myProcess) {
    myProcess.on("uncaughtException", () => { ... });
}

if (require.main === module) { // to prevent this from executing when running unit tests
    main(process);
}

My unit tests would do:

const fakeProcess = jasmine.createSpy("process", ["on"]);
main(fakeProcess);



回答8:


I ran into the same problem when testing React components using mocha and enzyme.

I was able to solve my problem by explicitly unmounting components after I had finished testing them.

The issue was that I was mounting components multiple times in my tests, which were then adding more listeners, until the number of listeners got to 11, and I got a warning.

I changed my test code by adding the rendered.unmount() line. This fixed the problem for me.

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

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


来源:https://stackoverflow.com/questions/15581978/nodejs-how-to-debug-eventemitter-memory-leak-detected-11-listeners-added

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!