2014-11-26 8 views
5

Ich bin gerade fertig geworden, um meine erste node.js App zu entwickeln und jetzt teste ich sie auf meinem VPS. Beobachten die Verwendung von Ressourcen des Prozesses "Knoten", habe ich eine Zunahme der Speicherbelegung festgestellt, wenn eine Seite (insbesondere einige) angefordert wird. Insbesondere wenn die angeforderte Seite eine statische Seite ist, ist die Zunahme minimal. Wenn die angeforderte Seite/admin ist, kann die Erhöhung 1mb sein! Wenn/admin angefordert wird, tut mein Server natürlich mehr, als eine statische Seite zu bedienen. Er verbindet sich mit mongodb, er führt 4 "find" aus, er bindet die Ergebnisse an eine HTML-Vorlage mit bind. Nun, was ist das Problem? Dieser Speicher wird niemals freigegeben !!! Also dachte ich, dass es einen logischen Fehler in meinem Code gab, aber dann habe ich einen anderen Test viel interessanter gemacht.Verwendeter Speicher wird nie im Knoten js freigegeben. Sehr seltsam

Betrachten Sie diese sehr einfach NodeJS Server:

var http = require('http'); 
http.createServer(function (req, res) { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
    res.end('Hello World\n'); 
}).listen(3000, 'my_public_ip'); 

wenn ich mit Browser mehrere Anfragen zu machen versuchen (einfach durch f5 eine Minute lang halten), Speicherverbrauch wächst langsam und die für den Prozess im Speicher wird nie veröffentlicht werden, auch nach einer langen Zeit und nach dem Schließen des Browsers. Nun ist es wahrscheinlich, dass es in meinem/admin Code einen Fehler gibt (1 MB Arbeitsspeicher und nie freigegeben für jede Anfrage ist es sehr hoch!), Aber ich denke, dass es sehr seltsam ist, dass der vom obigen Skript verwendete Speicher niemals freigegeben wird ! Was denkst du darüber? Es gibt eine Möglichkeit, es zu vermeiden?

Auch (in meinem realen Server), habe ich memwatch in thys Weise:

var memwatch = require('memwatch'); 
    memwatch.on('leak', function(info) { 
     console.log(info); 
     process.exit(1); 
    }); 

Wenn ich mehrere Anfragen mit Browser ausführen, nach ca. 10 Sekunden, die ich es tue, wird der Prozess beenden und das ist der Fehler:

{ start: Wed Nov 26 2014 08:21:07 GMT-0500 (EST), 
    end: Wed Nov 26 2014 08:22:04 GMT-0500 (EST), 
    growth: 4775624, 
    reason: 'heap growth over 5 consecutive GCs (57s) - 287.65 mb/hr' } 

Was bedeutet es ?? Es scheint mit Garbage Collector verwandt zu sein! Ich weiß, dass es besser wäre, meinen/admin-Code hier einzufügen, aber das Snippet ist sehr lang und hat mit globalen Variablen zu tun, so ist es unmöglich, ohne eine Kopie von 200 Zeilen zu verstehen: D. Wenn Sie mehr Informationen benötigen, werde ich Ihnen geben!

+1

Haben Sie versucht, die Speicherbereinigung manuell zu erzwingen? Überprüfen Sie http://devjar.me/post/22886448979/manually-run-gc-in-node-js: "Starten Sie den Knoten mit den Flags -nouse_idle_notification und -expose_gc. Wenn Sie den GC ausführen möchten, rufen Sie einfach global auf .gc(). " – Joel

+0

Sie können Ihren Code in einem gist/pastebin veröffentlichen. Aber die einfache Tatsache, dass Sie globale Variablen erwähnen, sollte eine Warnung auslösen :) Wir brauchen mehr Informationen. Versuchen Sie auch, den Hot-Code zu "memwatch", nicht gleich nach dem Start. – randunel

+0

Ich (Andras) versuchte den obigen Code mit erzwungenem GC, und es ist sehr sehr langsam, aber etwas geht weiter. Über 200 Sekunden und 580.000 Aufrufe heapUsed gingen um 40KB (winziges Bit), aber heapTotal stieg um 12MB, zuerst +4 dann +8. Ich laufe jetzt einen 5min Lauf – Andras

Antwort

5

Es ist nicht überraschend, dass Knoten Speicher nicht freigibt, die meisten Programme nicht. Sie sind gierig: Wenn sie knapp werden, bekommen sie mehr Speicher vom System. Wenn sie extra haben, behalten sie es für später.

Der kurze Beispielserver hat keinen Speicherverlust. Ich habe einen 14-minütigen Test mit Knoten v0.10.29 durchgeführt; Der Speicherverbrauch wächst nur anfänglich langsam, dann hört er auf. Die Wachstumsrate beträgt weniger als ein Bit pro HTTP-Aufruf, daher kann in den Aufrufen selbst kein Speicher ausgelaufen sein. Es ist möglich, dass die Speicherfragmentierung, die durch die Laufzeit von nodejs verursacht wird, zu einem Heap-Wachstum führen kann, bis genügend Ersatzspeicher vorhanden ist, um die Fragmentierung auszugleichen.

Nach 14 Minuten verwendete der nodejs-Prozess immer noch nur 2MB aus seinem 21MB-Heap, wie zu Beginn. (14, weil der 15-min-Lauf wurde pausiert für 1:09)

Hier ist das Wachstum über 2,46 Millionen http Aufrufe (zeigt nur die heapTotal Änderungen und final. Der endgültige Speicherbedarf ist nach 4 Minuten erreicht, und ändert sich nicht für die nächsten 11 min):

2014-12-03T04: 52: {48.358Z RSS: 12.222.464, heapTotal: 7.130.752, heapUsed: 1.751.228}
2014-12-03T04: 52: {55.182Z RSS: 17.326.080 heapTotal,: 9227904, heapUsed: 2186528}
2014-12-03T04: 53: {59.488Z RSS: 21.172.224, heapTotal: 13.422.208, heapUsed: 2.092.796}
2014-12-03T04: 56: {58.897Z RSS: 29.556.736 , heapTotal: 21810816, heapUsed: 2100000 }
(...wurde für 01.09 um 05.02.27)
2014-12-03T05 pausiert: 07: 45.598Z {rss: 29446144, heapTotal: 21810816, heapUsed: 2.138.608}

My (leicht modifiziert) Test:

var ncalls = 0; 
var http = require('http'); 
http.createServer(function (req, res) { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
    res.end('Hello World\n'); 
    if (ncalls++ % 100000 === 0) { 
    global.gc(); 
    console.log(new Date().toISOString(), process.memoryUsage()); 
    } 
}).listen(3000, '127.0.0.1'); 
console.log("Listening on 3000..."); 
Verwandte Themen