patternjavascriptMinor
Node.js script may have memory leak
Viewed 0 times
scriptmaynodeleakmemoryhave
Problem
I use this node.js script to migrate MongoDB collection to a schema to another. It does work if the collection is <20k documents, but slows down to a crawl and sometime throw a
FATAL ERROR: JS Allocation failed - process out of memory
Is it because of a memory leak? Or the intensive call to
My guess is that if the mongoDB server fast enough to the save/too many documents, callback piles up and eat the CPU/RAM away and end up crashing the script.
Is my guess right? Is there a memory leak? What can I do to speed up the script/fix existing error(s)?
```
var fs = require('fs'),
mongoose = require('mongoose'),
db = {}, //db.read will be the connection to the collection to migrate, db.write to the collection to migrate to
S_logs = {}, //Mongoose schema (read and write)
M_logs = {}, //Mongoose models (read and write)
config, //Config file
launched = 0,//Number of document migration started
ended = 0, //Number of document migration finished
percent = 0, //Used to calculate the progress bar
stats = {
ok: 0, //Number of succesful migration
error: 0 //Number of failed migration
};
function getCollection(callback) {
console.log('|0% |10% |20% |30% |40% |50% |60% |70% |80% |90% |100%')
M_logs.read.count({}, function (err, count) {
var stream = M_logs.read.find().stream(); //Stream the entire collection, document by document
stream.on('data', function (document) {
launched = launched + 1;
//Adapt the document to the new schema
var P_log = {};
for (name in config.write.data) {
if (config.write.data.hasOwnProperty(name)) {
P_log[name] = document[name] || '';
}
}
//Clear the queue
process.nextTick(function () {
//Save the new document
FATAL ERROR: JS Allocation failed - process out of memory
Is it because of a memory leak? Or the intensive call to
process.nextTick() (once per document)?My guess is that if the mongoDB server fast enough to the save/too many documents, callback piles up and eat the CPU/RAM away and end up crashing the script.
Is my guess right? Is there a memory leak? What can I do to speed up the script/fix existing error(s)?
```
var fs = require('fs'),
mongoose = require('mongoose'),
db = {}, //db.read will be the connection to the collection to migrate, db.write to the collection to migrate to
S_logs = {}, //Mongoose schema (read and write)
M_logs = {}, //Mongoose models (read and write)
config, //Config file
launched = 0,//Number of document migration started
ended = 0, //Number of document migration finished
percent = 0, //Used to calculate the progress bar
stats = {
ok: 0, //Number of succesful migration
error: 0 //Number of failed migration
};
function getCollection(callback) {
console.log('|0% |10% |20% |30% |40% |50% |60% |70% |80% |90% |100%')
M_logs.read.count({}, function (err, count) {
var stream = M_logs.read.find().stream(); //Stream the entire collection, document by document
stream.on('data', function (document) {
launched = launched + 1;
//Adapt the document to the new schema
var P_log = {};
for (name in config.write.data) {
if (config.write.data.hasOwnProperty(name)) {
P_log[name] = document[name] || '';
}
}
//Clear the queue
process.nextTick(function () {
//Save the new document
Solution
Interesting question,
It seems you are using a ton of closures. 13 out of 15
I would simply declare every one of those functions as a named function, it should already help a ton. And then indeed build some queue so that you are not DOS'ing your own machine.
It seems you are using a ton of closures. 13 out of 15
function definitions are anonymous functions. I cant find a single one that is capturing anything useful since you have a ton of global variables on top.I would simply declare every one of those functions as a named function, it should already help a ton. And then indeed build some queue so that you are not DOS'ing your own machine.
Context
StackExchange Code Review Q#70721, answer score: 2
Revisions (0)
No revisions yet.