manipulation - jsdom y node.js pierden memoria
nodejs dom (4)
Encontré algunas referencias a personas que tienen un problema similar donde la respuesta siempre fue, asegúrese de llamar a window.close () cuando haya terminado. Sin embargo, eso no parece funcionar para mí (nodo 0.8.14 y jsdom 0.3.1)
Una simple reproducción
var util = require(''util'');
var jsdom=require(''jsdom'');
function doOne() {
var htmlDoc = ''<html><head></head><body id="'' + i + ''"></body></html>'';
jsdom.env(htmlDoc, null, null, function(errors, window) {
window.close();
});
}
for (var i=1;i< 100000;i++ ) {
doOne();
if(i % 500 == 0) {
console.log(i + ":" + util.inspect(process.memoryUsage()));
}
}
console.log ("done");
La salida que obtengo es
500:{ rss: 108847104, heapTotal: 115979520, heapUsed: 102696768 }
1000:{ rss: 198250496, heapTotal: 194394624, heapUsed: 190892120 }
1500:{ rss: 267304960, heapTotal: 254246912, heapUsed: 223847712 }
...
11000:{ rss: 1565204480, heapTotal: 1593723904, heapUsed: 1466889432 }
En este punto, el ventilador se vuelve loco y la prueba se detiene ... o al menos comienza a ir muy lentamente
¿Alguien tiene otros consejos aparte de window.close para deshacerse de la pérdida de memoria (o parece una fuga de memoria)?
¡Gracias!
Peter
Tuve el mismo problema con jsdom y cambio a cheerio , que es mucho más rápido que jsdom y funciona incluso después de escanear cientos de sitios. Quizás deberías intentarlo también. El único problema es que tiene dos selectores que puede usar en jsdom.
Espero que funcione para usted también.
Daniel
No le está dando al programa ningún tiempo de inactividad para hacer la recolección de basura. Creo que se encontrará con el mismo problema con cualquier gráfico de objeto grande creado muchas veces con fuerza en un bucle sin interrupciones.
Esto se confirma con la respuesta de CheapSteaks, que fuerza manualmente la recolección de basura. No puede haber una pérdida de memoria en jsdom si eso funciona, ya que las pérdidas de memoria por definición evitan que el recolector de basura recolecte la memoria filtrada.
con un trago, uso de memoria, limpieza, eliminación de variables, window.close ()
var gb = setInterval(function () {
//only call if memory use is bove 200MB
if (process.memoryUsage().heapUsed > 200000000) {
global.gc();
}
}, 10000); // 10sec
gulp.task(''tester'', [''clean:raw2''], function() {
return gulp.src(''./raw/*.html'')
.pipe(logger())
.pipe(map(function(contents, filename) {
var doc = jsdom.jsdom(contents);
var window = doc.parentWindow;
var $ = jquery(window);
console.log( $(''title'').text() );
var html = window.document.documentElement.outerHTML;
$( doc ).ready(function() {
console.log( "document loaded" );
window.close();
});
return html;
}))
.pipe(gulp.dest(''./raw2''))
.on(''end'', onEnd);
});
y tenía constantemente entre 200mb - 300mb de uso, para archivos 7k. tomó 30 minutos. Podría ser útil para alguien, ya que busqué en Google y no encontré nada útil.
Usando jsdom 0.6.0 para ayudar a raspar algunos datos y se encontró con el mismo problema.
window.close
solo ayudó a ralentizar la pérdida de memoria, pero finalmente se arrastró hasta que el proceso fue asesinado.
Ejecutando el script con el node --expose-gc myscript.js
Hasta que solucionen la pérdida de memoria, al llamar manualmente al recolector de basura, además de llamar a window.close
parece funcionar:
if (process.memoryUsage().heapUsed > 200000000) { // memory use is above 200MB
global.gc();
}
Atascado después de la llamada a window.close. El uso de la memoria vuelve inmediatamente a la línea de base (alrededor de 50 MB para mí) cada vez que se activa. Alto apenas perceptible.