2012-08-27 88 views
2

我的裸骨Node.js應用看起來像這樣(實際上我經常調用Web服務,並將這些數據推送給客戶端)經過一天左右,我得到即使在添加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. 

並不意味着 '創建發射器對象,並添加emitter.setMaxListeners(0)到您的代碼'。詞'emitter'在這裏指的是從EventEmitter繼承的ANY對象,例如服務器,進程,請求等等。在你的情況下,你在顯示的代碼中有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將是100而不是10 – zag2art