Hier gibt es zwei Fragen.
Warum benötigt das Programm so viel Speicher?
Ich denke, es liegt am fehlenden Gegendruck.
Ihr Skript sendet nur 1 Million Veröffentlichungsbefehle an Redis, verarbeitet jedoch keine Antwort auf diese Befehle (die daher von node_redis einfach verworfen werden). Da es nie auf eine Antwort wartet, sammelt das Skript für all diese Befehle viel Kontext im Speicher. node_redis muss einen Kontext behalten, um die Befehle zu verfolgen und Redis-Befehle und -Antworten zuzuordnen. Node.js kann Befehle schneller in die Warteschlange einreihen, als das System diese Befehle an Redis übermitteln, sie verarbeiten, Antworten erstellen und Antworten zurück an node.js übermitteln muss. Der Kontext wächst daher und stellt viel Speicher dar.
Wenn Sie den Speicherverbrauch auf einem akzeptablen Niveau halten möchten, müssen Sie Ihren Code drosseln, um node.js die Möglichkeit zu geben, Redis-Antworten zu verarbeiten. Das folgende Skript verarbeitet beispielsweise auch 1 Million Elemente, veröffentlicht sie jedoch als Stapel von 1000 Elementen und wartet alle 1000 Elemente auf die Antworten. Es verbraucht daher sehr wenig Speicher (der Kontext enthält höchstens 1000 ausstehende Befehle).
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);
Kann der Speicher freigegeben werden?
Normalerweise kann es das nicht. Wie alle C/C++-Programme verwendet node.js einen Speicherzuordner. Wenn Speicher freigegeben wird, wird er nicht an das System, sondern an den Speicherzuordner freigegeben. Im Allgemeinen ist der Speicherzuordner nicht in der Lage, den ungenutzten Speicher an das System zurückzugeben. Bitte beachten Sie, dass es sich nicht um ein Leck handelt, da der Speicher wiederverwendet wird, wenn das Programm eine neue Zuordnung durchführt.
Das Schreiben eines C/C++-Programms, das tatsächlich Speicher für das System freigeben kann, beinhaltet im Allgemeinen das Entwerfen eines benutzerdefinierten Speicherzuordners. Nur wenige C/C++-Programme können das. Darüber hinaus enthält node.js einen Garbage Collector mit v8, daher sollte es zusätzliche Einschränkungen für die Speicherfreigaberichtlinie geben.