обнаружена возможная утечка памяти EventEmitter



Я получаю следующее предупреждение:



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


Я написал такой код на сервере.js:



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


Как это исправить ?

888   15  

15 ответов:

Это объясняется в руководстве: http://nodejs.org/docs/latest/api/events.html#events_emitter_setmaxlisteners_n

что это за Версия узла? Какой еще код у вас есть? Это ненормальное поведение.

в: process.setMaxListeners(0);

Смотрите также: узел.js-запрос-как "эмиттер.setMaxListeners ()"?

Я хотел бы указать здесь, что это предупреждение существует по какой-то причине, и есть хороший шанс, что правильное исправление не увеличение предела, но выяснить, почему вы добавляете так много слушателей к тому же событию. Только увеличить лимит, если вы знаете, почему так много слушателей добавляются и уверены, что это то, что вы действительно хотите.

Я нашел эту страницу, потому что я получил это предупреждение, и в моем случае была ошибка в каком-то коде, который я использовал, который превращал глобальный объект в EventEmitter! Я бы, конечно, не советовал увеличивать лимит глобально, потому что вы не хотите, чтобы эти вещи оставались незамеченными.

по умолчанию для любого отдельного события может быть зарегистрировано не более 10 слушателей.

если это ваш код, вы можете указать maxListeners через:

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

но если это не ваш код вы можете использовать трюк, чтобы увеличить лимит по умолчанию глобально:

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

конечно, вы можете отключить ограничения, но будьте осторожны:

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

кстати. Код должен быть в самом начале приложения.

добавить: начиная с узла 0.11 этот код также работает изменить ограничение по умолчанию:

require('events').EventEmitter.defaultMaxListeners = 0

принятый ответ предоставляет семантику о том, как увеличить лимит, но, как указал @voltrevo, предупреждение существует по какой-то причине, и ваш код, вероятно, имеет ошибку.

рассмотрим следующий код багги:

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

теперь обратите внимание на правильный способ добавления слушателя:

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

поиск подобных проблем в коде перед изменением maxListeners (что объясняется в других ответах)

заменить .на () С один раз(). использование функции once () удаляет прослушиватели событий, когда событие обрабатывается той же функцией. источник: http://nodeguide.com/beginner.html#using-eventemitters

Если это не исправить, то переустановите restler с этим в вашем пакете.формат JSON "restler": "в git://github-е. ком/danwrong/restler.в Git#9d455ff14c57ddbe263dbbcd0289d76413bfe07d"

Это связано с неправильным поведением restler 0.10 с узлом. вы можете увидеть, что проблема закрыта ГИТ здесь:https://github.com/danwrong/restler/issues/112 однако npm еще не обновил это, поэтому вам нужно обратиться к главе git.

happy restling:)

Я получаю это предупреждение тоже при установке aglio на моем mac osx.

Я использую cmd исправить это.

sudo npm install -g npm@next

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

в моем случае, это был child.stderr.pipe(process.stderr) который вызывался, когда я инициировал 10 (или около того) экземпляров ребенка. Поэтому все, что приводит к присоединению обработчика событий к одному и тому же объекту EventEmitter в цикле, заставляет nodejs выдавать эту ошибку.

иногда эти предупреждения возникают, когда это не то, что мы сделали, но то, что мы забыли сделать!

Я столкнулся с этим предупреждением, когда я установил пакет dotenv с npm, но был прерван, прежде чем я приступил к добавлению require('dotenv').оператор load () в начале моего приложения. Когда я вернулся в проект, я начал получать предупреждения "возможная утечка памяти EventEmitter обнаружена".

Я предположил, что проблема была от чего-то, что у меня было сделано, а не то, чего я не делал!

Как только я обнаружил свою оплошность и добавил оператор require, предупреждение об утечке памяти было очищено.

у меня было это до сегодняшнего дня, когда я начинаю grunt watch. Наконец-то решено

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

раздражающее сообщение исчезло.

Вы сказали, что вы используете process.on('uncaughtException', callback);
Где вы выполняете это заявление? Это в пределах обратного вызова, переданного в http.createServer?
если да, то другая копия того же обратного вызова будет прикреплена к uncaughtException событие при каждом новом запросе, потому что function (req, res) { ... } выполняется каждый раз, когда приходит новый запрос, и так будет оператор process.on('uncaughtException', callback);
отметим, что объект процесса является глобальным для всех ваших запросов и добавления слушателей к его событию каждый раз, когда приходит новый запрос, это не имеет никакого смысла. Возможно, вы не захотите такого поведения.
если вы хотите прикрепить новый прослушиватель для каждого нового запроса, вы должны удалить все предыдущие прослушиватели, прикрепленные к событию, поскольку они больше не потребуются с помощью:
process.removeAllListeners('uncaughtException');

исправление нашей команды для этого было удаление пути реестра из нашего .npmrc. У нас было два псевдонима пути в rc-файле, и один указывал на искусственный экземпляр, который был устаревшим.

ошибка не имела ничего общего с фактическим кодом нашего приложения, но все сделать с нашей средой разработки.

У меня была та же проблема. и проблема была вызвана тем, что я слушал порт 8080, на 2 слушателей.

setMaxListeners() работает нормально, но я бы не советовал.

правильный способ-проверить свой код на наличие дополнительных слушателей, удалить слушателя или изменить номер порта, на котором вы слушаете, это исправило мою проблему.

Я обновился от старой версии LTS, 6 что-то, к новой версии LTS 8.9.4 и мои ошибки ушли.

Я предпочитаю выслеживать и исправлять проблемы вместо подавления журналов, когда это возможно. После нескольких дней наблюдения за этой проблемой в моем приложении я понял, что устанавливаю слушателей на req.socket в экспресс-промежуточном программном обеспечении, чтобы поймать ошибки ввода-вывода сокета, которые продолжали появляться. В какой-то момент я понял, что в этом нет необходимости, но все равно держал слушателей при себе. Я просто удалил их,и ошибка, которую вы испытываете, ушла. Я проверил, что это было причиной, запустив запросы на мой сервер со следующим промежуточным программным обеспечением и без него:

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

удаление этого промежуточного программного обеспечения остановило предупреждение, которое вы видите. Я бы посмотрел вокруг вашего кода и попытаться найти в любом месте вы можете настроить слушателей, которые вам не нужны.

поместите это в первую строку вашего сервера.js (или все, что содержит ваш основной узел.js app):

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

и ошибка исчезнет :)

Comments

    Ничего не найдено.