Há duas perguntas aqui.
Por que o programa requer tanta memória?
Eu acho que é devido à falta de pressão nas costas.
Seu script apenas envia 1 milhão de comandos de publicação para o Redis, mas não processa nenhuma resposta a esses comandos (que, portanto, são descartados pelo node_redis). Como ele nunca espera por nenhuma resposta, o script acumulará muito contexto na memória para todos esses comandos. node_redis precisa manter um contexto para acompanhar os comandos e associar comandos e respostas do Redis. O Node.js é mais rápido para enfileirar comandos do que o sistema para transmitir esses comandos para o Redis, processá-los, criar respostas e transmitir as respostas de volta ao node.js. O contexto está, portanto, crescendo, e representa muita memória.
Se você deseja manter o consumo de memória em um nível aceitável, precisa reduzir seu código para dar uma chance ao node.js de processar as respostas do Redis. Por exemplo, o script a seguir também processa 1 milhão de itens, mas os publica como lotes de 1.000 itens e aguarda as respostas a cada 1.000 itens. Portanto, consome muito pouca memória (o contexto contém no máximo 1.000 comandos pendentes).
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);
A memória pode ser liberada?
Normalmente, não pode. Como todos os programas C/C++, o node.js usa um alocador de memória. Quando a memória é liberada, ela não é liberada para o sistema, mas para o alocador de memória. Geralmente, o alocador de memória não é capaz de devolver a memória não utilizada ao sistema. Observe que não é um vazamento, pois se o programa realizar uma nova alocação, a memória será reutilizada.
Escrever um programa C/C++ que pode realmente liberar memória para o sistema geralmente envolve projetar um alocador de memória personalizado. Poucos programas C/C++ fazem isso. Além disso, o node.js inclui um coletor de lixo com v8, portanto, deve colocar restrições adicionais na política de liberação de memória.