possible fuite de mémoire D'EventEmitter détectée

je reçois l'avertissement suivant:

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

j'ai écrit ce code sur le serveur.js:

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

comment corriger cela ?

142
demandé sur Whymarrh 2012-03-19 14:20:59

15 réponses

ceci est expliqué dans le manuel: http://nodejs.org/docs/latest/api/events.html#events_emitter_setmaxlisteners_n

quelle version de Node est-ce? Quelles sont les autres code avez-vous? Ce n'est pas un comportement normal.

en bref, son: process.setMaxListeners(0);

Voir aussi: noeud.js - demande - Comment "de l'émetteur.setMaxListeners ()"?

72
répondu Corey Richardson 2017-05-23 11:54:59

je tiens à souligner ici que cet avertissement est là pour une raison et il ya une bonne chance que le bon correctif est pas augmenter la limite, mais de comprendre pourquoi vous ajoutez tant d'auditeurs à la même événement. N'augmentez la limite que si vous savez pourquoi tant d'auditeurs sont ajoutés et que vous êtes sûr que c'est ce que vous voulez vraiment.

j'ai trouvé cette page parce que j'ai eu cet avertissement et dans mon cas, il y avait un bug dans le code que j'utilisais ce transformait l'objet global en un EventEmitter! Je conseillerais certainement de ne pas augmenter la limite à l'échelle mondiale parce que vous ne voulez pas que ces choses passent inaperçues.

121
répondu voltrevo 2015-07-16 00:18:18

par défaut, un maximum de 10 auditeurs peuvent être enregistrés pour n'importe quel événement.

si c'est votre code, vous pouvez spécifier des maxListeners via:

const emitter = new EventEmitter()
emitter.setMaxListeners(100)
// or 0 to turn off the limit
emitter.setMaxListeners(0)

mais si ce n'est pas votre code, vous pouvez utiliser l'astuce pour augmenter la limite par défaut globalement:

require('events').EventEmitter.prototype._maxListeners = 100;

bien sûr, vous pouvez désactiver les limites mais attention:

// turn off limits by default (BE CAREFUL)
require('events').EventEmitter.prototype._maxListeners = 0;

BTW. Le code doit être au tout début de l'application.

ajouter: depuis le noeud 0.11 ce code fonctionne aussi pour changer la limite par défaut:

require('events').EventEmitter.defaultMaxListeners = 0
62
répondu zag2art 2018-07-25 08:21:31

la réponse acceptée fournit la sémantique sur la façon d'augmenter la limite, mais comme @voltrevo a souligné que l'avertissement est là pour une raison et votre code a probablement un bug.

Considérez les points suivants du code bogué:

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

Maintenant, observez la bonne façon d'ajouter l'auditeur:

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

rechercher des problèmes similaires dans votre code avant de changer les maxListeners (ce qui est expliqué dans d'autres réponses)

30
répondu RLaaa 2018-04-23 18:32:59

de remplacer .() avec(). en utilisant une fois() enlève les écouteurs d'événement lorsque l'événement est géré par la même fonction. source: http://nodeguide.com/beginner.html#using-eventemitters

si cela ne le corrige pas, réinstallez restler avec ceci dans votre paquet.json "restler": "git: / / github.com / danwrong / restler.git#9d455ff14c57ddbe263dbbcd0289d76413bfe07d "

cela a à voir avec restler 0.10 mauvais comportement avec noeud. vous pouvez voir le numéro clos sur git ici: https://github.com/danwrong/restler/issues/112 cependant, npm n'a pas encore mis à jour cela, de sorte que c'est pourquoi vous devez faire référence à la tête git.

heureux restling :)

13
répondu Davis Dulin 2013-12-17 00:46:19

je reçois cet avertissement aussi quand installer aglio sur mon Mac osx.

j'utilise cmd le fixer.

sudo npm install -g npm@next

https://github.com/npm/npm/issues/13806

3
répondu Legolas Bloom 2016-09-28 01:46:02

dans mon cas, c'était child.stderr.pipe(process.stderr) qui a été appelé quand j'ai initié 10 (ou plus) cas de l'enfant. Ainsi, tout ce qui conduit à attacher un handler d'événement au même objet EventEmitter dans une boucle, provoque nodejs à lancer cette erreur.

1
répondu Vikas Gautam 2016-11-22 02:28:29

parfois ces avertissements se produisent quand ce n'est pas quelque chose que nous avons fait, mais quelque chose que nous avons oublié de faire!

j'ai rencontré cet avertissement lorsque j'ai installé le paquet dotenv avec npm, mais j'ai été interrompu avant de pouvoir ajouter le require('dotenv').load() déclaration au début de mon application. Quand je suis retourné au projet, j'ai commencé à recevoir les Avertissements "fuite possible de mémoire EventEmitter détectée".

j'ai supposé que le problème était de quelque chose que j'avais fait, pas quelque chose que je n'avais pas fait!

une fois que j'ai découvert mon erreur et que j'ai ajouté La mention require, l'alarme de fuite de mémoire s'est dissipée.

1
répondu Motate 2017-01-21 18:59:10

Je l'avais jusqu'à aujourd'hui quand je commence grunt watch . Enfin résolu par

watch:{
        options:{
            maxListeners: 99,
            livereload: true
        },
}

le message ennuyeux est parti.

1
répondu Ariful Haque 2017-05-11 06:51:25

vous avez dit que vous utilisiez process.on('uncaughtException', callback);

Où en êtes-vous de l'exécution de cette instruction? Est-ce que ça fait partie du rappel passé à http.createServer ?

si oui, une copie différente du même callback sera attachée à l'événement uncaughtException à chaque nouvelle requête, parce que le function (req, res) { ... } est exécuté chaque fois qu'une nouvelle requête Entre et de la même manière sera la déclaration process.on('uncaughtException', callback); 151960920 "
noter que le objet de processus est global à toutes vos demandes et en ajoutant les auditeurs de son événement, à chaque fois, une nouvelle demande ne fait aucun sens. Vous ne voudrez peut-être pas d'un tel comportement.

dans le cas où vous voulez joindre un nouvel auditeur pour chaque nouvelle demande, vous devez supprimer tous les anciens auditeurs attachés à l'événement car ils ne seraient plus nécessaires en utilisant:

process.removeAllListeners('uncaughtException');

0
répondu Monish Chhadwa 2016-07-06 13:41:16

la solution de notre équipe était de supprimer un chemin d'enregistrement de notre .npmrc. Nous avions deux alias de chemin dans le fichier rc, et l'un pointait vers une instance artificielle qui avait été dépréciée.

L'erreur n'avait rien à voir avec le code actuel de notre application mais tout à voir avec notre environnement de développement.

0
répondu RossO 2017-04-20 23:40:24

j'avais le même problème. et le problème a été causé parce que j'écoutais port 8080, sur 2 auditeurs.

setMaxListeners() fonctionne bien, mais je ne le recommanderais pas.

la bonne façon est de, vérifier votre code pour les auditeurs supplémentaires, supprimer l'auditeur ou changer le numéro de port sur lequel vous écoutez, cela a corrigé mon problème.

0
répondu Noman Abid 2018-01-24 12:35:06

je suis passé de l'ancienne version LTS, 6 quelque chose, à la nouvelle version LTS 8.9.4 et mes erreurs ont disparu.

0
répondu maxpaj 2018-02-08 07:27:43

je préfère traquer et résoudre les problèmes au lieu de supprimer les rondins dans la mesure du possible. Après quelques jours d'observation de ce problème dans mon application, j'ai réalisé que j'installais des écouteurs sur le req.socket dans un middleware Express pour détecter les erreurs de socket io qui n'arrêtaient pas de surgir. À un moment donné, j'ai appris que ce n'était pas nécessaire, mais j'ai gardé les auditeurs autour de toute façon. Je viens de les enlever et l'erreur que vous rencontrez a disparu. J'ai vérifié que c'était la cause en lançant des requêtes à mon serveur avec et sans 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();
    }

supprimer cet middleware a arrêté l'avertissement que vous voyez. Je regarderais autour de votre code et essayerais de trouver n'importe où vous pourriez mettre en place des auditeurs dont vous n'avez pas besoin.

0
répondu lwdthe1 2018-08-12 13:47:05

mettez ceci dans la première ligne de votre serveur.js (ou ce qui contient votre noeud principal.js app):

require('events').EventEmitter.prototype._maxListeners = 0;

et le message d'erreur disparaît :)

-1
répondu Sebastian 2016-02-10 13:02:19