“JavaScript se queda sin memoria” mientras se transmite un archivo grande

Estoy tratando de XML -> JSON -> MongoDB en mi servidor. Tengo una aplicación NodeJS que transmite el XML, lo convierte en JSON y luego lo agrega al servidor MongoDB en partes de 1000. Sin embargo, después de aproximadamente 75000 registros, los fanáticos de mi Macbook comienzan a girar más rápido y el procesamiento es REALMENTE lento. Después de unos minutos, me sale este error:

[30517: 0x102801600] 698057 ms: Mark-sweep 1408.2 (1702.9) -> 1408.1 (1667.4) MB, 800.3 / 0.0 ms (+ 0.0 ms en 0 pasos desde el inicio de la marca, el paso mayor 0.0 ms, tiempo en la pared desde el inicio de la marca 803 ms) último recurso [30517: 0x102801600] 698940 ms: Mark-sweep 1408.1 (1667.4) -> 1408.1 (1667.4) MB, 882.2 / 0.0 ms último recurso

y finalmente en el stacktrace de JS:

ERROR FATAL: CALL_AND_RETRY_LAST Fallo en la asignación – montón de JavaScript fuera de la memoria

Tengo la sensación de que mi memoria se está agotando, pero boost la memoria permitida con --max-old-space-size (o lo que sea) no funciona cuando el archivo tiene más de 70 gigabytes y solo tengo 16 GB de RAM.

Aquí está el código de lo que estoy tratando de hacer:

 var fs = require('fs'), path = require('path'), XmlStream = require('xml-stream'), MongoClient = require('mongodb').MongoClient, url = 'mongodb://username:password@my.server:27017/mydatabase', amount = 0; MongoClient.connect(url, function(err, db) { var stream = fs.createReadStream(path.join(__dirname, 'motor.xml')); var xml = new XmlStream(stream); var docs = []; xml.collect('ns:Statistik'); // This is your event for the element matches xml.on('endElement: ns:Statistik', function(item) { docs.push(item); // collect to array for insertMany amount++; if ( amount % 1000 === 0 ) { xml.pause(); // pause the stream events db.collection('vehicles').insertMany(docs, function(err, result) { if (err) throw err; docs = []; // clear the array xml.resume(); // resume the stream events }); } }); // End stream handler - insert remaining and close connection xml.on("end",function() { if ( amount % 1000 !== 0 ) { db.collection('vehicles').insertMany(docs, function(err, result) { if (err) throw err; db.close(); }); } else { db.close(); } }); }); 

Mi pregunta es algo como: ¿Tengo una pérdida de memoria? ¿Por qué Node permite que el código construya la memoria de esa manera? ¿Hay una solución además de comprar más de 70 GB de RAM para mi PC?

Publicar mi comentario como respuesta, ya que resolvió el problema y podría ser útil para otras personas que tienen dificultades para usar el paquete xml-stream de esta manera.

En cuestión, el método de collect está causando el problema ya que obliga al analizador a recostackr todas las instancias del nodo procesado en una matriz a medida que se analizan. collect solo debe utilizarse para recostackr elementos secundarios de un determinado tipo de cada nodo que se está analizando. El comportamiento predeterminado es no hacerlo (debido a la naturaleza de transmisión del analizador que le permite procesar archivos de varios gigabytes con facilidad).

Así que la solución fue eliminar esa línea de código y simplemente usar el evento endElement .