Il y a deux questions ici.
Pourquoi le programme nécessite-t-il autant de mémoire ?
Je pense que c'est dû au manque de contre-pression.
Votre script envoie juste 1M de commandes de publication à Redis, mais il ne traite aucune réponse à ces commandes (qui sont donc simplement rejetées par node_redis). Comme il n'attend jamais de réponse, le script accumulera beaucoup de contexte en mémoire pour toutes ces commandes. node_redis doit conserver un contexte pour suivre les commandes et associer les commandes et les réponses Redis. Node.js est plus rapide pour mettre les commandes en file d'attente que le système pour transmettre ces commandes à Redis, les traiter, créer des réponses et renvoyer les réponses à node.js. Le contexte est donc grandissant, et il représente beaucoup de mémoire.
Si vous souhaitez maintenir la consommation de mémoire à un niveau acceptable, vous devez réduire votre code pour donner une chance à node.js de traiter les réponses Redis. Par exemple, le script suivant traite également 1 million d'éléments, mais il les publie sous forme de lots de 1 000 éléments et attend les réponses tous les 1 000 éléments. Il consomme donc très peu de mémoire (le contexte contient au maximum 1000 commandes en attente).
var redis = require("redis"),
publisher = redis.createClient();
function loop( callback ) {
var count = 0;
for ( i=0 ; i < 1000; ++i ) {
publisher.publish("rChat", i, function(err,rep) {
if ( ++count == 1000 )
callback();
});
}
}
function loop_rec( n, callback ) {
if ( n == 0 ) {
callback();
return;
}
loop( function() {
loop_rec( n-1, callback );
});
}
function main() {
console.log("Hello");
loop_rec(1000, function() {
console.log("stopped sending messages");
setTimeout(function(){publisher.end();},1000);
return;
});
}
publisher.ping(main)
setTimeout(function() {
console.log("Keeping console alive");
}, 1000000);
La mémoire peut-elle être libérée ?
Habituellement, ce n'est pas possible. Comme tous les programmes C/C++, node.js utilise un répartiteur de mémoire. Lorsque la mémoire est libérée, elle n'est pas libérée sur le système, mais sur l'allocateur de mémoire. Généralement, l'allocateur de mémoire n'est pas en mesure de restituer la mémoire inutilisée au système. Attention, il ne s'agit pas d'une fuite, car si le programme effectue une nouvelle allocation, la mémoire sera réutilisée.
L'écriture d'un programme C/C++ capable de libérer de la mémoire sur le système implique généralement la conception d'un répartiteur de mémoire personnalisé. Peu de programmes C/C++ le font. En plus de cela, node.js inclut un ramasse-miettes avec v8, il devrait donc imposer des contraintes supplémentaires sur la politique de libération de mémoire.