NodeJS: как отладить "обнаружена утечка памяти EventEmitter. 11 слушателей добавили"
как я могу отладить свое приложение, которое выдает эту ошибку:
(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)
Я не мог найти предполагаемый объект утечки для увеличения предела слушателя на .setMaxListeners(0);
решение (от fardjad и Ян А. Салава)
с поисками Яна салавы я нашел рабочую библиотеку (longjohn) для увеличения трассировки стека подробно. В ответ fardjad я обнаружил, что у нас есть прототип EventEmitter.addListener
и EventEmitter.on
.
С решением я мог бы получить этот новый след:
(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)
7 ответов
оказывается, что это ошибка в ядре nodejs, мы говорим об этой проблеме здесь:
https://github.com/joyent/node/issues/5108
решение для прослушиваемых http-серверов, которые бросают EventEmitter memory leak detected
и заполнить доступную память / доступное время процессора :
вернуться к прежней версии v0.8.23
.
Вы можете скачать и установить/скомпилировать его из здесь :
для меня похоже, что ваш цикл событий заблокирован. Это может произойти, если вы выполняете задачи с интенсивным процессором в узле.цикл событий js. Вы можете использовать дочерний процесс сделать много задач.
вы можете проверить, что блокирует узел.Яш, используя следующие методы:
- мера исчисления времени каждого вызова. Журнал, если время высокое, так что вы знаете, приложение плохо себя ведет.
- настроить расписание журнала, чтобы вы знали, когда что-то блокирующее петлю
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);
- использовать профиль.
- использовать этой для ведения журнала и профилирования. Это библиотека, используемая в Nodejitsu.
Это именно то, что случилось со мной. Для меня я случайно вложил прослушиватель событий в другой прослушиватель событий.
посмотрите на свой код и убедитесь, что у вас нет блока прослушивателя событий в другом блоке прослушивателя событий, например(если вы не делаете это специально):
socket.on('data', function(data) {
//code goes here
socket.on('close' , function() {
//code goes here
});
});
в неправильном примере выше, сокет.on ('close') прослушиватель должен находиться вне сокета.on('data') блок.
в моем случае, когда я получил 5 потоков данных, розетка.прослушиватель on('close') ожидает события close. Когда я закрываю один раз, выполняется еще одно 4-е событие закрытия. Это явно не то, чего я хотел. Это связано с природой узла.js, который не блокируется. Он "запоминает" события из-за функции обратного вызова.
Я попытался создать прототип EventEmitter для добавления сообщений журнала в addListener, но я не мог заставить его работать
крючком addListener
вы можете сделать что-то вроде этого:
// 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);
}
Это предупреждение будет выдано, если вы зарегистрируетесь для определенного события одного и того же объекта более 11 раз.
проверьте, есть ли у вас вызов " on " для события particualr в функции, которую вы вызываете часто, это приводит к регистрации события несколько раз.
этой link помог мне понять это.
поскольку узел 6 Вы должны использовать node --trace-warnings
: https://nodejs.org/api/cli.html#cli_trace_warnings
я столкнулся с той же проблемой при тестировании реагировать компоненты с помощью МОКа и фермент.
я смог решить свою проблему, явно размонтировав компоненты после того, как я закончил их тестирование.
проблема заключалась в том, что я монтировал компоненты несколько раз в своих тестах, которые затем добавляли больше слушателей, пока количество слушателей не достигло 11, и я получил предупреждение.
Я поменяла тестовый код, добавив вынесено.unmount () линии. Это исправило проблему для меня.
describe('<CircleArc />', () => {
it('renders', function () {
const rendered = mount(<CircleArc />);
assert.ok(rendered.find('path'));
rendered.unmount();
});
}