NodeJS: Cómo depurar “Se detectó fuga de memoria EventEmitter. 11 oyentes añadieron “

¿Cómo puedo depurar mi aplicación que arroja este 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) 

No pude encontrar el supuesto objeto de fuga para boost el límite de escucha por .setMaxListeners(0);

SOLUCIÓN (de fardjad y jan salawa)

Con las búsquedas de jan salawa encontré una biblioteca de trabajo ( longjohn ) para boost los rastros de stack detallados. Con la respuesta de fardjad, he descubierto que tenemos que prototipo EventEmitter.addListener AND EventEmitter.on .

Con la solución podría obtener este nuevo rastro:

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

Resulta que esto es un error en el núcleo de nodejs, estamos hablando de este problema aquí:

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

Solución para servidores http con EventEmitter memory leak detected que arroja una EventEmitter memory leak detected y llena la memoria disponible / tiempos de CPU disponibles:

v0.8.23 versión heredada v0.8.23 .

Puede descargarlo e instalarlo / comstackrlo desde aquí:

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

Para mí, parece que tu bucle de eventos está bloqueado. Esto puede suceder si realiza tareas intensivas de CPU en el bucle de evento node.js. Puede usar el proceso hijo para realizar una tarea intensiva.

Puede verificar lo que está bloqueando node.js usando los siguientes métodos :

  1. Mida el tiempo de cálculo de cada llamada. Inicie sesión si el tiempo es alto para que sepa que la aplicación se está portando mal.
  2. Configure un horario de registro para que sepa cuándo algo está bloqueando el bucle
     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. Usar perfil
  4. Use esto para registrar y perfilar. Es una biblioteca utilizada en Nodejitsu .

Esto es exactamente lo que me sucedió a mí. Para mí, he nested un detector de eventos dentro de otro detector de eventos accidentalmente.

Mire su código y asegúrese de NO tener un bloque de escucha de eventos DENTRO de otro bloque de escucha de eventos por ejemplo (a menos que lo haga a propósito):

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

En el ejemplo incorrecto anterior, el oyente socket.on (‘close’) debe estar FUERA del bloque socket.on (‘data’).

En mi caso, cuando recibí 5 flujos de datos, el oyente socket.on (‘close’) está esperando que ocurra un evento cercano. Cuando cierro una vez, se ejecutará otro cuarto evento de cierre. Esto claramente no es lo que yo quería. Esto se debe a la naturaleza de Node.js que no es bloqueante. ‘Recuerda’ eventos debido a la función de callback.

Intenté prototipar el EventEmitter para agregar mensajes de registro en addListener pero no pude hacerlo funcionar

Para conectar addListener puede hacer algo como esto:

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

Esta advertencia se lanzará si se registra para un evento particular de un mismo objeto más de 11 veces.

Verifique si tiene una llamada “activada” para un evento particular en una función a la que está llamando con frecuencia, esto lleva a registrarse para un evento varias veces.

Este enlace me ayudó a entender esto.

Desde el nodo 6, debe usar el node --trace-warnings : https://nodejs.org/api/cli.html#cli_trace_warnings

Me encontré con el mismo problema cuando probaba los componentes React usando mocha y enzima .

Pude resolver mi problema desmontando explícitamente los componentes después de que terminé de probarlos.

El problema era que estaba montando componentes varias veces en mis pruebas, que luego estaban agregando más oyentes, hasta que el número de oyentes llegó a 11, y recibí una advertencia.

Cambié mi código de prueba al agregar la línea rendered.unmount () . Esto solucionó el problema para mí.

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