Тук има два въпроса.
Защо програмата изисква толкова много памет?
Мисля, че се дължи на липсата на обратно налягане.
Вашият скрипт просто изпраща 1M команди за публикуване на Redis, но той не обработва никакъв отговор на тези команди (които следователно просто се изхвърлят от node_redis). Тъй като никога не чака никакъв отговор, скриптът ще натрупа много контекст в паметта за всички тези команди. node_redis трябва да поддържа контекст, за да следи командите, и да асоциира Redis команди и отговори. Node.js е по-бърз за поставяне на команди в опашка, отколкото системата е да предаде тези команди на Redis, да ги обработва, да създава отговори и да предава отговорите обратно към node.js. Следователно контекстът се разраства и представлява много памет.
Ако искате да поддържате консумацията на памет на приемливо ниво, трябва да намалите кода си, за да дадете шанс на node.js да обработва отговорите на Redis. Например, следният скрипт също обработва 1M елемента, но ги публикува като партиди от 1000 елемента и чака отговорите на всеки 1000 елемента. Следователно той консумира много малко памет (контекстът съдържа най-много 1000 чакащи команди).
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);
Може ли да се освободи паметта?
Обикновено не може. Както всички C/C++ програми, node.js използва разпределител на паметта. Когато паметта се освободи, тя не се освобождава към системата, а към разпределителя на паметта. По принцип разпределителят на паметта не е в състояние да върне неизползваната памет на системата. Моля, имайте предвид, че това не е теч, защото ако програмата извърши ново разпределение, паметта ще бъде използвана повторно.
Написването на C/C++ програма, която действително може да освободи памет в системата, обикновено включва проектиране на персонализиран разпределител на паметта. Малко C/C++ програми го правят. Освен това, node.js включва колектор за боклук с v8, така че трябва да постави допълнителни ограничения върху политиката за освобождаване на паметта.