2015-06-10 29 views
6

nodejs Ve basit bir soket uygulaması (sadece bağlayın ve bağlantıyı kesmek) için socket.io kullanarak kod yazdım, yaklaşık 50 kullanıcı belleği kullanımı için çok değişmez, ama 300'e kadar kullanıcı ve bir saat sonra, bellek kullanımı sadece büyür (server.js proccess için yaklaşık 300MB ve zaman geçtikçe büyür), node'lerin belleğini serbest bırakmaması gibi görünüyor.nodejs, socket.io basit kod bellek sızıntısı

var server = require('http').createServer(); 
var io = require('socket.io')(server); 
var port = 9090; 
var sockets = {}; 

server.listen(port, function() { 
    console.log('Server listening at port ', port); 
    //timer and logs are not problem , i tested it before. 
    setInterval(function(){ 
     console.log(Object.keys(sockets).length+' Online Devices At '+Date()); 
    }, 1000 * 60 * 1); 
}); 

io.on('connection',function(socket){ 
    sockets[socket.id]={id:socket.id}; 
    console.log('connected '+socket.id + ' count ' + Object.keys(sockets).length); 
    socket.on('disconnect', function (data) { 
     delete sockets[socket.id]; 
     console.log('disconnected '+socket.id+ ' count ' +Object.keys(sockets).length); 
    }); 
}); 

Bazı şeyleri yanlış yapıyorum?

Düzenleme

14 saat forever enter image description here

300 açık yuva ile Ve nodejs proccess ilgilidir bellek kullanımı 500MB Hakkında dosyasını başlattıktan sonra.

Düzenleme

16 sonra Saat, süreç durdu enter image description here sonra 300 Bağlı Yuva. Yeni kodu enter image description here

Düzenleme

yağma ediniz. 100MB, 5 dakika 1000 stabil açık bağlantı sonrası: 400MB

var server = require('http').createServer(); 
var io = require('socket.io')(server); 
var port = 90; 
var counter = 0; 
var clients = {} 
server.listen(port, function() { 
     console.log('Server listening at port ', port); 
}); 
io.on("connection",function(socket){ 
     clients[socket.id] = socket; 
     counter++; 

     socket.on('disconnect', function (data) { 
       counter--; 
       delete clients[socket.id]; 
     }); 
}); 

i 1000 Bağlı kullanıcı ile bu çalışıyorum başlangıç ​​öncesinde

bellek kullanımı (başka sunucu benzetmek kullanıcı istekleri ve açık prizler olan)

cevap

0

Kod güzel görünüyor. Önerilen bellek sızıntısı, paylaştığınız kodun neredeyse hiçbir yerinde bulunmuyor.

Bu ana soruya uygun değildir, ama sadece bağlı soketi sayısını listelemek istiyorsanız, bu gibi yerine sockets nesne üzerinde Object.keys() çağıran bir tamsayı sayacı kullanmalıdır:

var express = require('express'); 
var app  = express(); 
var server = require('http').createServer(app); 
var io  = require('socket.io')(server); 

var port = 9090; 
var connectedSockets = 0; 
var sockets = {}; 

server.listen(port, function() { 
    console.log('Server listening at port ', port); 
    //timer and logs are not problem , i tested it before. 
    setInterval(function(){ 
     console.log(connectedSockets + ' Online Devices At ' + Date()); 
    }, 1000 * 60 * 1); 
}); 

io.on('connection',function(socket){ 
    if (!sockets[socket.id]) connectedSockets++; 
    sockets[socket.id]={ id: socket.id }; 
    console.log('connected ' + socket.id + ' count ' + connectedSockets); 
    socket.on('disconnect', function (data) { 
     delete sockets[socket.id]; 
     connectedSockets--; 
     console.log('disconnected ' + socket.id + ' count ' + connectedSockets); 
    }); 
}); 
+0

Yuva nesnesi zaten bağlı soketlerin bir listesi olduğunda bir sayacı el ile ne koruyor? Bunun sorulan soruyla ne ilgisi var? – jfriend00

+0

@galactocalypse, ilk cevabınız için teşekkürler, ama önerilen bellek sızıntısı neredeyse paylaştığınız kodun bir parçası değil. . “Soketleri saymakla ilgili” biliyorum bunu! ama problemin değişkenleri veya dizi öğelerini göstermeyle ilgili olduğunu göstermeye çalıştım. – Mojtabye

+0

@ jfriend00: Bu noktanın başlangıcında, 'Bu, ana sorunuza uygun değil' demişti. Object.keys() O (n) 'de çalışır ve 300 fazla değilken, O (1) kesinlikle daha yüksek bir ölçekte tercih edilir. @ ALU0075: Burada bir yığın çöp toplamanızı ve burada önerildiği gibi bulduğunuz şeyi paylaşmanızı öneriyorum: http://jpallen.net/2013/03/08/tracking-down-a-memory-leak-in-node-js -ve-socket-io/'Ayrıca kullandığınız düğüm ve yuva sürümlerini de paylaşın. – galactocalypse

9

Kullanılmayan belleği boşaltmaya gelince V8, bu nedenle sadece V8'in çöp toplayıcısını çalıştırmadığı zaman bir bellek sızıntısı gibi görünebilir. Durumun böyle olup olmadığını görmek için, prosesinizi --expose-gc bayrak seti ile çalıştırın.

node --expose-gc yourscript.js 

Ve manuel çöp toplama işlemini bir aralıkta zorla (30 saniyelik aralıklarla kullandım).

setInterval(function(){ 
    global.gc(); 
    console.log('GC done') 
}, 1000*30); 
+0

teşekkürler, ama yeni koduma bakın! , 1000 soketinin ayrılmasından sonra ve dizi boyutu 0 ile ve herhangi bir kayıt olmadan bile, 5 dakika için 300MB fazladır: | – Mojtabye

+0

İstemci nesnesini koddan tamamen kaldırırsanız ne olur? Hala sızıntıyla karşılaşıyor musun? –

+1

Aynı SON! , bende bu konuda bir şeyler olduğunu hissediyorum. – Mojtabye