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 в функции, которую вы часто вызываете, это приводит к регистрации для события несколько раз.
этой ссылка помогла мне понять это.
С узла 6, Вы должны использовать
node --trace-warnings: https://nodejs.org/api/cli.html#cli_trace_warnings
я столкнулся с той же проблемой при тестировании реагировать компоненты с помощью МОКа и фермент.
я смог решить свою проблему, явно размонтировав компоненты после того, как я закончил их тестирование.
проблема заключалась в том, что я монтировал компоненты несколько раз в своих тестах, которые затем добавляли больше слушателей, пока количество слушателей не достигло 11, и я получил предупреждение.
Я поменяла тестовый код, добавив вынесено.размонтировать() линии. Это исправило проблему для меня.
describe('<CircleArc />', () => { it('renders', function () { const rendered = mount(<CircleArc />); assert.ok(rendered.find('path')); rendered.unmount(); }); }
Comments