2012-08-27 5 views
2

맨손으로 뼈가있는 Node.js 앱이 이렇게 생겼습니다 (본질적으로 모든 웹 서비스를 자주 호출하고 클라이언트에 데이터를 푸시합니다). 하루 정도 지나면 emitter.setMaxListeners (0)를 추가 한 후에도 실행 중 오류가 발생했습니다. 내 코드에는 메모리 누수가 없다는 것이 확실하다. 어떤 충고?Node.js "EventEmitter 메모리 누수가 감지되었습니다"

/* 
* Server setup 
*/ 
var querystring = require('querystring'); 
var xml2js = require('xml2js'); 
var parser = new xml2js.Parser(); 
var eyes = require('eyes'); 
var http = require('http'); 
var app = http.createServer(handler); 
var io = require('socket.io').listen(app); 
var emitter = new (require('events').EventEmitter); 
emitter.setMaxListeners(0); 
io.set('log level', 0); 

app.listen(8080); 


function handler(req, res){ 
    res.writeHead(200, {'Content-Type':'text/html'}); 
    res.end('Test'); 
} 

/* 
* Global data object 
*/ 
var xmlData= ''; 
var cache = []; 

/* 
* web service info 
*/ 
var postData = querystring.stringify({ 
    'index' : '', 
    'type' : '-1', 
}); 


var options = { 
    host: 'localhost', 
    path: '/WebService.asmx', 
    method: 'POST', 
    headers: { 
     'Content-Type': 'application/x-www-form-urlencoded', 
     'Content-Length': postData.length 
    } 
}; 



var getData = function(){ 

    // Web Service Request Obj 
    var webServiceReq = http.request(options, function(res) { 

     res.setEncoding('utf8'); 

     res.on('data', function (chunk) { 
     xmlData += chunk; 
     }).on('end', function() { 

     parser.parseString(xmlData, function(err, data){ 
       cache = JSON.parse(data['#']); 
     }); 

     io.sockets.emit('message', { "data": cache}); 

     });// end res.on('end') 

    }); 


    webServiceReq.write(postData); 
    webServiceReq.end(); 
} 

// grab the info every 10 seconds 
setInterval(getData, 5000); 

// emit the latest data when client initially connects 
io.sockets.on('connection', function (socket) { 
    // emit the data 
    socket.emit('message', {"data": cache}); 
}); 

오류 :

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. 
Trace 
    at Parser.EventEmitter.addListener (events.js:168:15) 
    at Parser.exports.Parser.Parser.parseString (C:\WebApplications\WebApp\scripts\node_modules\xml2js\lib\xml2js.js:197:14) 
    at Parser.__bind [as parseString] (C:\WebApplications\WebApp\scripts\node_modules\xml2js\lib\xml2js.js:6:61) 
    at IncomingMessage.getData (C:\WebApplications\WebApp\scripts\nodeService.js:87:20) 
    at IncomingMessage.EventEmitter.emit (events.js:115:20) 
    at IncomingMessage._emitEnd (http.js:366:10) 
    at HTTPParser.parserOnMessageComplete [as onMessageComplete] (http.js:149:23) 
    at Socket.socketOnData [as ondata] (http.js:1356:20) 
    at TCP.onread (net.js:410:27) 

답변

5

문제는

Use emitter.setMaxListeners() to increase limit. 

말은 '이미 터 객체를 생성 (0) 코드에 emitter.setMaxListeners 추가'를하지 않는다는 것입니다. Word 'emitter'는 EventEmitter에서 상속 한 객체를 가리 킵니다. 서버, 프로세스, 요청 등등. 귀하의 경우에는 표시된 코드에서 2 개의 이미 터가 있습니다 : app 및 io. 사용자가 작성해야한다는 것은 : 당신이 세계적으로 한도를 늘리려면

var http = require('http'); 
var app = http.createServer(handler); 
var io = require('socket.io').listen(app); 
app.setMaxListeners(0); 
io.setMaxListeners(0); 
io.set('log level', 0); 

app.listen(8080); 
+1

감사합니다! 이것은 확실히 도움이되었지만 몇 시간 동안 실행 한 후에 다음과 같은 오류가 발생했습니다. "치명적인 오류 : CALL_AND_RETRY_2 할당이 실패했습니다 - 메모리가 부족합니다.".. 내 응용 프로그램에 메모리 누수가 있음을 의미합니까? 나는 그것을 추적했고 나는 100 % 메모리 누수가 없다고 확신한다. 아니면 setTimeout() 함수와 관련이 있습니까? – victormejia

+1

@victorswx 내가 틀렸다고 정정 해 주겠지 만, 전역 객체 인 xmlData를 지우지 않는 것 같이 보입니다. xmlData + = chunk; NodeJS 프로세스는 제한된 크기의 메모리를 할당 할 수 있으며 약간 증가시킬 수 있습니다. 그러나, 귀하의 경우에는 어떻게 든 xmlData를 사용하는 논리를 변경해야합니다. –

2

이 앱의 시작 부분에 선을 배치 : 당신의 도움에 대한 require('events').EventEmitter.prototype._maxListeners = 100;

+0

이 작업의 영향은 무엇입니까? –

+0

디폴트의 maxListeners는 10 대신에 100이됩니다. – zag2art

관련 문제