Tengo un lector de RSS/MongoDB/raspador que se ejecuta a través de un conjunto de datos más grande que mi sistema tiene memoria para. A medida que recorro los datos, el sistema se ralentiza. Estoy razonablemente seguro de que es porque me estoy quedando sin memoria.¿Cómo puedo decodificar el significado de los datos de memoria en node.js y depurar la pérdida de memoria?
He agregado algo de información de depuración y he realizado algunos cambios, pero no sé cómo leer la información proporcionada en la salida de depuración.
He aquí una muestra de salida de depuración (desde antes de que sea mortal):
100 items
Memory: { rss: 11104256, // what is RSS?
vsize: 57507840, // what is VSIZE?
heapTotal: 4732352, // heapTotal?
heapUsed: 3407624 } // heapUsed?
200 items
Memory: { rss: 12533760,
vsize: 57880576,
heapTotal: 6136320,
heapUsed: 3541984 }
// what key numbers do I watch for?
// when do I reach 'situation critical'?
// how do I free up memory to prevent problems?
Además, si ayuda y para una mejor ilustración, he incluido una muestra del código. Un cambio que ya hice es mover todas las instrucciones de solicitud fuera de la función de GrabRss.
var http = require('http');
var sys = require('sys');
var xml2js = require('xml2js');
var util = require('util');
var Db = require('../lib/mongodb').Db,
Conn = require('../lib/mongodb').Connection,
Server = require('../lib/mongodb').Server,
// BSON = require('../lib/mongodb').BSONPure;
BSON = require('../lib/mongodb').BSONNative;
GrabRss = function(grab, start) {
var options = {
host: 'www.example.com',
port: 80,
path: '/rss/'+grab+'/'+start
};
var data;
var items;
var checked = 0;
var len = 0;
GotResponse = function(res) {
var ResponseBody = "";
res.on('data', DoChunk);
res.on('end', EndResponse);
function DoChunk(chunk){
ResponseBody += chunk;
}
function EndResponse() {
//console.log(ResponseBody);
var parser = new xml2js.Parser();
parser.addListener('end', GotRSSObject);
parser.parseString(ResponseBody);
}
}
GotError = function(e) {
console.log("Got error: " + e.message);
}
GotRSSObject = function(r){
items = r.item;
//console.log(sys.inspect(r));
var db = new Db('rss', new Server('localhost', 27017, {}), {native_parser:false});
db.open(function(err, db){
db.collection('items', function(err, col) {
len = items.length;
if (len === 0) {
process.exit(0);
}
for (i in items) {
SaveItem(item[i], col);
}
});
});
}
SaveMovie = function(i, c) {
c.update({'id': i.id}, {$set: i}, {upsert: true, safe: true}, function(err){
if (err) console.warn(err.message);
if (++checked >= len) {
if (checked < 5000) {
delete data; // added since asking
delete items; // added since asking
console.log(start+checked);
console.log('Memory: '+util.inspect(process.memoryUsage()));
GrabRss(50, start+checked);
} else {
console.log(len);
process.exit(0);
}
} else if (checked % 10 == 0) {
console.log(start+checked);
}
});
}
http.get(options, GotResponse).on('error', GotError);
}
GrabRss(50, 0);
gracias. La siguiente marca parece haber suavizado realmente el procesamiento. ¿Alguna idea de lo que significan los valores de memoria (rss, vsize, heaptotal, heapused)? La documentación aquí http://nodejs.org/docs/v0.4.8/api/all.html#process.memoryUsage no entra en detalles. –
Un consejo con nextTick: es una llamada muy, muy rápida. Node.js tiene un único subproceso en un bucle de eventos, como todos saben. El uso de nextTick ejecutará literalmente esa función en el próximo ciclo, asegúrate de no llamar con mucha frecuencia, de lo contrario te encontrarás perdiendo ciclos. – tjarratt
Y con respecto a rss, vsize, heaptotal, heapused ... vsize es el tamaño completo de la memoria que está usando su proceso y rss es la cantidad de eso en la RAM física real y no en el intercambio. Teaptotal y heapused se refieren al almacenamiento subyacente de v8 del que usted no tiene control. – tjarratt