Il semblerait que j'ai une fuite de mémoire avec mon application Node.js. Je l'ai construite rapidement, et mon JavaScript n'est pas trop fort, donc cela pourrait être facile.
J'ai fait quelques captures d'écran de la mémoire, et c'est l'objet String object
qui fuit en mémoire, à un rythme d'environ 1 Mo toutes les 5 minutes. J'ai élargi String, et c'est en fait String.Array?
#!/usr/local/bin/node
var port = 8081;
var io = require('socket.io').listen(port),
sys = require('sys'),
daemon = require('daemon'),
mysql = require('mysql-libmysqlclient');
var updateq = "SELECT 1=1";
var countq = "SELECT 2=2";
io.set('log level', 2);
process.on('uncaughtException', function(err) {
console.log(err);
});
var connections = 0;
var conn = mysql.createConnectionSync();
dbconnect();
io.sockets.on('connection', function(client){
connections++;
client.on('disconnect', function(){ connections--; })
});
process.on('exit', function () {
console.log('Sortie');
dbdisconnect();
});
function dbdisconnect() {
conn.closeSync();
}
function dbconnect() {
conn.connectSync('leet.hacker.org','user','password');
}
function update() {
if (connections == 0)
return;
conn.query(updateq, function (err, res) {
if (err) {
dbdisconnect();
dbconnect();
return;
}
res.fetchAll(function (err, rows) {
if (err) {
throw err;
}
io.sockets.json.send(rows);
});
});
}
function totals() {
if (connections == 0)
return;
conn.query(countq, function (err, res) {
if (err) {
// Il est probable que le serveur vient de se déconnecter, essayons de nous reconnecter
dbdisconnect();
dbconnect();
throw err;
}
res.fetchAll(function (err, rows) {
if (err) {
throw err;
}
io.sockets.json.send(rows);
});
});
}
setInterval(update, 250);
setInterval(totals,1000);
setInterval(function() {
console.log("Nombre de connexions : " + connections);
},1800000);
daemon.daemonize('/var/log/epiclog.log', '/var/run/mything.pid', function (err, pid) {
// Nous sommes maintenant dans le processus du démon
if (err) return sys.puts('Erreur lors du démarrage du démon : ' + err);
sys.puts('Démon démarré avec succès avec PID : ' + pid);
});
Version actuelle
function totals() {
if (connections > 0)
{
var q = "SELECT query FROM table";
db.query(q, function (err, results, fields) {
if (err) {
console.error(err);
return false;
}
for (var row in results)
{
io.sockets.send("{ ID: '" + results[row].ID + "', event: '" + results[row].event + "', free: '" + results[row].free + "', total: '" + results[row].total + "', state: '" + results[row]$
row = null;
}
results = null;
fields = null;
err = null;
q = null;
});
}
}
Toujours une fuite de mémoire, mais cela semble se produire uniquement dans ces conditions :
- Depuis le démarrage, sans clients -> Bon
- 1ère connexion client -> Bon
- 2ème client (même si le 1er client se déconnecte et se reconnecte) -> Fuite de mémoire
- Arrêt de toutes les connexions -> Bon
- 1 nouvelle connexion (connections = 1) -> Fuite de mémoire
1 votes
Informatif : stackoverflow.com/questions/5733665/…
7 votes
connectSync
:(0 votes
Vous mentionnez avoir modifié String pour contenir String.Array, et même nous indiquer cela dans votre capture d'écran de mémoire, mais je ne vois rien dans votre code qui utiliserait cela, ni ce que vous avez réellement fait pour créer String.Array.
0 votes
@Raynos: Je sais, je dois trouver un meilleur client MySQL.
0 votes
@Matt, Je n'utilise pas String.Array. C'est juste ce que j'ai remarqué augmentait dans la mémoire des instantanés du tas.
0 votes
Lorsque vous dites qu'elle augmente à un rythme de 1 Mo / 5 minutes, combien de connexions est-ce? Si vous augmentez le nombre de connexions, la fuite augmente-t-elle plus rapidement? Et en proportion du nombre de messages envoyés par le client?
0 votes
@Matt - Je l'exécutais en mode de débogage, donc une seule connexion (moi).
0 votes
@Matt - Le client n'envoie aucun message de retour au serveur. En ce qui concerne le Serveur -> Client: update() génère environ 10 à 20 messages par 'tick'. totals() est d'environ 25 messages par seconde.
0 votes
J'ai comparé les tas de heap au début et à la fin de mes deux fonctions, et ils n'augmentent pas en mémoire. Cela doit donc provenir d'un composant que j'utilise.
0 votes
Mises à jour : J'ai remplacé le mysql-libmysqlclient par seulement mysql (paquet npm), et il n'y a aucun changement à ce niveau. J'ai remarqué qu'il y a une augmentation lorsque : Lorsque le premier utilisateur se connecte, l'utilisation de la mémoire est normale, c'est génial Lorsque cet utilisateur se reconnecte, ou un autre utilisateur se connecte, nous commençons à perdre de la mémoire Tous les utilisateurs se déconnectent, tout va bien 1 nouvelle personne se connecte, et nous perdons à nouveau de la mémoire Donc, je pense que c'est quelque chose lié à socket.io. J'utilise la nouvelle version qui a été publiée la semaine dernière.
0 votes
Je soupçonnerais que la sérialisation JSON soit au moins liée à la fuite - l'avez-vous exécutée sans
io.sockets.json.send
?0 votes
@Wladimir Palant - J'ai essayé cela (juste en envoyant le JSON en tant que chaîne de caractères), et ça fuit toujours la mémoire. J'ai édité le message initial avec la copie actuelle de l'une des fonctions.
5 votes
@giggsey semble être une fuite de socket.io. Allez déposer un bug
0 votes
Pour tous : J'ai soumis un rapport de bogue aux développeurs de Socket.IO, et ils sont en train de l'examiner : github.com/LearnBoost/socket.io/issues/299