programing

NodeJS :“EventEmitter 메모리 누수가 감지되었습니다.

goodcopy 2021. 1. 15. 19:19
반응형

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 및 jan salawa에서 제공)

1월 salawa의 검색으로 내가 작업 라이브러리 (발견 longjohn을 상세 스택 추적을 증가). fardjad의 응답으로 EventEmitter.addListener AND 프로토 타입을 만들어야한다는 것을 알았습니다 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)

이것이 nodejs 코어의 버그 인 것으로 밝혀졌습니다. 여기서이 문제에 대해 이야기하고 있습니다. https://github.com/joyent/node/issues/5108

EventEmitter memory leak detected사용 가능한 메모리 / 사용 가능한 CPU 시간을 발생시키고 채우는 버그가있는 http 서버에 대한 솔루션 :

기존 버전으로 되돌 v0.8.23립니다. ( http://blog.nodejs.org/2013/04/08/node-v0-8-23-legacy/ 에서 다운로드하여 설치 / 컴파일 할 수 있습니다. )

업데이트 2018 : 이 주제에 대한 몇 가지 피드백이 있지만 문제는 수년 동안 사라진 것 같습니다. 이 응답은 nodejs를 사용하는 누출 http 서버 빌드에만 해당됩니다 . 다른 시나리오에있는 경우이 스레드에서 다른 응답을 확인하고 버전을 다운 그레이드하지 마십시오 (이 응답에서 제안한대로). 시간을 낭비하게됩니다.


저에게는 이벤트 루프가 차단 된 것 같습니다. 이는 node.js 이벤트 루프에서 CPU 집약적 인 작업을 수행하는 경우 발생할 수 있습니다. 하위 프로세스사용 하여 집중적 인 작업을 수행 할 수 있습니다 .

다음 방법을 사용하여 node.js를 차단하는 것을 확인할 수 있습니다 .

  1. 각 호출의 계산 시간측정 합니다. 시간이 많으면 기록하여 앱이 오작동하고 있음을 알 수 있습니다.
  2. 어떤 것이 루프를 차단하는지 알 수 있도록 로그 일정 설정
    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);
  3. 프로필을 사용 합니다.
  4. 로깅 및 프로파일 링에 사용 합니다 . Nodejitsu 에서 사용되는 라이브러리 입니다.

이것이 바로 나에게 일어난 일입니다. 나를 위해 실수로 다른 이벤트 리스너 내에 이벤트 리스너를 중첩했습니다.

코드를보고 예를 들어 다른 이벤트 리스너 블록 내에 이벤트 리스너 블록이 없는지 확인하십시오 (의도적으로 수행하지 않는 한).

socket.on('data', function(data) {
//code goes here

socket.on('close' , function() {
//code goes here
     });

   });

위의 잘못된 예에서 socket.on ( 'close') 리스너는 socket.on ( 'data') 블록의 외부에 있어야합니다.

제 경우에는 5 개의 데이터 스트림을 받았을 때 socket.on ( 'close') 리스너가 닫기 이벤트가 발생하기를 기다리고 있습니다. 한 번 닫으면 또 다른 네 번째 닫는 이벤트가 실행됩니다. 이것은 분명히 내가 원하는 것이 아닙니다. 이는 차단되지 않는 Node.js의 특성 때문입니다. 콜백 함수로 인한 이벤트를 '기억'합니다.


addListener에 로그 메시지를 추가하기 위해 EventEmitter 프로토 타입을 시도했지만 작동하지 못했습니다.

연결하려면 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'호출이 있는지 확인하면 이벤트에 여러 번 등록하게됩니다.

링크는 이것을 이해하는 데 도움이되었습니다.


Since node 6 you should use node --trace-warnings: https://nodejs.org/api/cli.html#cli_trace_warnings


I was seeing this when I was running my unit tests. My unit tests were repeatedly calling code that was calling:

process.on("uncaughtException", () => { ... });

I had to use dependency injection to inject a fake process object, which solved the problem.

main.js:

export function main(myProcess) {
    myProcess.on("uncaughtException", () => { ... });
}

if (require.main === module) { // to prevent this from executing when running unit tests
    main(process);
}

My unit tests would do:

const fakeProcess = jasmine.createSpy("process", ["on"]);
main(fakeProcess);

I ran into the same problem when testing React components using mocha and enzyme.

I was able to solve my problem by explicitly unmounting components after I had finished testing them.

The issue was that I was mounting components multiple times in my tests, which were then adding more listeners, until the number of listeners got to 11, and I got a warning.

I changed my test code by adding the rendered.unmount() line. This fixed the problem for me.

describe('<CircleArc />', () => {

    it('renders', function () {
        const rendered = mount(<CircleArc />);
        assert.ok(rendered.find('path'));
        rendered.unmount();
    });
}

ReferenceURL : https://stackoverflow.com/questions/15581978/nodejs-how-to-debug-eventemitter-memory-leak-detected-11-listeners-added

반응형