[英]NODE.JS: FATAL ERROR- JS Allocation failed - process out of memory, while parsing large json objects
I am trying to parse and add into mongodb database some data that am getting from an API. 我正在尝试解析并向mongodb数据库添加一些从API获取的数据。 I want to get all the data for every user from specific time till today.
我希望从特定时间到今天为每个用户获取所有数据。 So what I am doing is, I am retrieving for each user data for 5 days for each iteration, so its like 2-3 month data seperating into 5 days.
所以我正在做的是,我每次迭代检索每个用户数据5天,所以它就像2-3个月的数据分成5天。
For some reason I am getting this error with the Allocation Failer - Process out of memory. 出于某种原因,我收到了Allocation Failer的错误 - 处理内存不足。
Seems like I get this error at the time when I arrive at a particular user, cz he seems having more data than others. 似乎我在到达特定用户时遇到此错误,因为他似乎比其他人拥有更多数据。
I did tried this command when running the script: node --max-old-space-size=4028 worksnap.js. 我在运行脚本时尝试过这个命令:node --max-old-space-size = 4028 worksnap.js。
My code looks like this: 我的代码看起来像这样:
var currentMonth = new Date();
var startDate = new Date("February 1, 2016 00:00:00"); //Start from February
var counter = 1;
while (startDate.getMonth() <= currentMonth.getMonth()) {
//todo:: look if u have to increaze the start time, due the previous end time becomes start time it can take the same time time entries (have to be reviewd and make sure)....
var from = new Date(startDate).getTime() / 1000;
startDate.setDate(startDate.getDate() + 5);
var to = new Date(startDate).getTime() / 1000;
iterateThruAllStudents(from, to);
}
function getTimeEntriesFromWorksnap(error, response, body) {
//console.log(response.statusCode);
if (!error && response.statusCode == 200) {
parser.parseString(body, function (err, results) {
var json_string = JSON.stringify(results.time_entries);
var timeEntries = JSON.parse(json_string);
_.forEach(timeEntries, function (timeEntry) {
_.forEach(timeEntry, function (item) {
saveTimeEntry(item);
});
});
});
}
}
function saveTimeEntry(item) {
Student.findOne({
'worksnap.user.user_id': item.user_id[0]
})
.populate('user')
.exec(function (err, student) {
if (err) {
throw err;
}
student.timeEntries.push(item);
student.save(function (err) {
if (err) {
console.log(err);
} else {
console.log('item inserted...');
}
});
});
}
function iterateThruAllStudents(from, to) {
Student.find({status: 'student'})
.populate('user')
.exec(function (err, students) {
if (err) {
throw err;
}
_.forEach(students, function (student, i) {
if (student.worksnap.user != null) {
setTimeout(function () {
var options = {
url: 'https://api.worksnaps.com/api/projects/' + project_id + '/time_entries.xml?user_ids=' + student.worksnap.user.user_id + '&from_timestamp=' + from + '&to_timestamp=' + to,
headers: {
'Authorization': 'Basic bGhNSVwJkVUFasSxx2loOFVyZkFyOENEZEsdxxxCdUlHdElWMHo0czo='
}
};
request(options, getTimeEntriesFromWorksnap);
}, 5000 * i);
}
});
});
}
Anyone knows what I am doing wrong here? 谁知道我在做错了什么?
This is more a comment, as it does not contain a solution. 这是一个评论,因为它不包含解决方案。
There are two things that looks fishy : 有两件事看起来很可疑 :
One problem is with: 一个问题是:
while (startDate.getMonth() <= currentMonth.getMonth()) {
//todo:: look if u have to increaze the start time, due the previous end time becomes start time it can take the same time time entries (have to be reviewd and make sure)....
var from = new Date(startDate).getTime() / 1000;
startDate.setDate(startDate.getDate() + 5);
var to = new Date(startDate).getTime() / 1000;
iterateThruAllStudents(from, to);
}
You don't wait until you process the data of one student, but you request the data of all students in parallel. 您不必等到处理一名学生的数据,而是同时请求所有学生的数据。
A similar problem is the setTimeout
, because depending on the execution time your code needs to hold the data of multiple requests in memory. 类似的问题是
setTimeout
,因为根据执行时间,您的代码需要在内存中保存多个请求的数据。
You should use something like async or Promise to solve asynchrone loops. 您应该使用async或Promise之类的东西来解决异步循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.