[Node.js] posible pérdida de memoria EventEmitter detectada



Answers

Me gustaría señalar aquí que esa advertencia está ahí por una razón y hay una buena posibilidad de que la solución correcta no aumente el límite, sino que averigüe por qué está agregando tantos oyentes al mismo evento. Solo aumente el límite si sabe por qué se están agregando tantos oyentes y confía en que es lo que realmente desea.

Encontré esta página porque recibí esta advertencia y en mi caso había un error en algún código que estaba usando y que convertía el objeto global en un EventEmitter. Ciertamente desaconsejaría aumentar el límite a nivel mundial porque no quieres que estas cosas pasen desapercibidas.

Question

Estoy recibiendo la siguiente advertencia:

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

Escribí un código como este en server.js:

http.createServer(
    function (req, res) { ... }).listen(3013);

Cómo arreglar esto ?




La respuesta aceptada proporciona la semántica sobre cómo aumentar el límite, pero como @voltrevo señaló que la advertencia está ahí por una razón y que su código probablemente tenga un error.

Considere el siguiente código buggy:

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

Ahora observe la forma correcta de agregar al oyente:

//Good: event listener is not in a loop
Logger.on('error', function (err) {
    console.log('error writing log: ' + err)
});

for (var i = 0; i < 11; i++) {
    Logger.writeLog('Hello');
}

Busque problemas similares en su código antes de cambiar los maxListeners (lo que se explica en otras respuestas)




A veces, estas advertencias ocurren cuando no es algo que hemos hecho, sino algo que hemos olvidado hacer.

Encontré esta advertencia cuando instalé el paquete dotenv con npm, pero me interrumpieron antes de agregar la declaración require ('dotenv'). Load () al principio de mi aplicación. Cuando volví al proyecto, comencé a recibir las advertencias de "Detección de fuga de memoria posible de EventEmitter".

¡Supuse que el problema era por algo que había hecho, no algo que no había hecho!

Una vez que descubrí mi supervisión y agregué la declaración requerida, se borró la advertencia de pérdida de memoria.




Dijiste que estás usando process.on('uncaughtException', callback);
¿Dónde estás ejecutando esta declaración? ¿Está dentro de la devolución de llamada pasada a http.createServer ?
Si es así, se adjuntará una copia diferente de la misma devolución de llamada al evento uncaughtException en cada nueva solicitud, porque la function (req, res) { ... } se ejecuta cada vez que entra una nueva solicitud y también lo hace el process.on('uncaughtException', callback); declaración.on process.on('uncaughtException', callback);
Tenga en cuenta que el objeto de proceso es global para todas sus solicitudes y agregar oyentes a su evento cada vez que ingrese una nueva solicitud no tendrá ningún sentido. Es posible que no desee ese tipo de comportamiento.
En caso de que desee adjuntar un nuevo oyente para cada nueva solicitud, debe eliminar todos los oyentes anteriores adjuntos al evento, ya que ya no serían necesarios mediante:
process.removeAllListeners('uncaughtException');







Prefiero cazar y solucionar problemas en lugar de eliminar registros cuando sea posible. Después de un par de días de observar este problema en mi aplicación, me di cuenta de que estaba configurando oyentes en el req.socket de req.socket En un middleware Express para detectar los errores de socket que seguían apareciendo. En algún momento, aprendí que eso no era necesario, pero de todos modos mantuve a los oyentes alrededor. Simplemente los eliminé y el error que experimentas desapareció. Comprobé que era la causa al ejecutar solicitudes a mi servidor con y sin el siguiente middleware:

socketEventsHandler(req, res, next) {
        req.socket.on("error", function(err) {
            console.error('------REQ ERROR')
            console.error(err.stack)
        });
        res.socket.on("error", function(err) {
            console.error('------RES ERROR')
            console.error(err.stack)
        });
        next();
    }

La eliminación de ese middleware detuvo la advertencia que está viendo. Revisaría su código e intentaría encontrar sitios donde pueda configurar oyentes que no necesita.




Estaba teniendo el mismo problema. y el problema fue causado porque estaba escuchando el puerto 8080, en 2 oyentes.

setMaxListeners() funciona bien, pero no lo recomendaría.

la forma correcta es verificar el código para detectar oyentes adicionales, eliminar el oyente o cambiar el número de puerto en el que está escuchando, esto solucionó mi problema.






Links