Jsou zde dvě otázky.
Proč program vyžaduje tolik paměti?
Myslím, že je to kvůli nedostatku zpětného tlaku.
Váš skript pouze odesílá 1M publikačních příkazů do Redis, ale nezpracovává žádnou odpověď na tyto příkazy (které jsou proto pouze zahozeny node_redis). Protože skript nikdy nečeká na žádnou odpověď, nashromáždí v paměti spoustu kontextu pro všechny tyto příkazy. node_redis potřebuje udržovat kontext, aby mohl sledovat příkazy a přidružovat příkazy a odpovědi Redis. Node.js je rychlejší při zařazování příkazů do fronty, než aby systém tyto příkazy předával Redis, zpracovával je, sestavoval odpovědi a předával odpovědi zpět do node.js. Kontext proto roste a představuje hodně paměti.
Pokud chcete udržet spotřebu paměti na přijatelné úrovni, musíte omezit svůj kód, abyste dali node.js šanci zpracovat odpovědi Redis. Například následující skript také zpracuje 1 milion položek, ale publikuje je jako dávky po 1 000 položkách a každých 1 000 položek čeká na odpovědi. Spotřebovává proto velmi málo paměti (kontext obsahuje maximálně 1000 čekajících příkazů).
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);
Lze paměť uvolnit?
Obvykle to nelze. Jako všechny programy v C/C++ i node.js používá alokátor paměti. Když se paměť uvolní, neuvolní se do systému, ale do alokátoru paměti. Obecně platí, že alokátor paměti není schopen vrátit nevyužitou paměť systému. Upozorňujeme, že nejde o únik informací, protože pokud program provede novou alokaci, paměť bude znovu použita.
Psaní programu C/C++, který může skutečně uvolnit paměť do systému, obecně zahrnuje navržení vlastního alokátoru paměti. Málokterý C/C++ program to umí. Kromě toho node.js obsahuje garbage collector s v8, takže by měl klást další omezení na politiku uvolňování paměti.