exports.updateFullCentralRecordSheet = function (req, _id, type) {
FullCentralRecordSheet.remove({_ExternalParty: _id, centralRecordType: type, centralSheetType: "Central Sheet"}, function (err) {
if (err) {
saveErrorLog(req, err);
}
let query = {"structure.externalPartyRelationships": {$elemMatch: {_ExternalParty: _id}}, disabled: {$mod: [2, 0]}, initialized: true, profitLossType: type};
let fullCentralRecordSheetObjects = [];
ProfitLossSheet.find(query).sort({profitLossDate: 1}).lean().exec(function (err, profitLossSheetObjects) {
if (err) {
saveErrorLog(req, err);
}
async.each(profitLossSheetObjects, function (profitLossSheetObject, callback) {
/// HEAVY COMPUTATION HERE
callback();
});
}, function (err) {
if (err) {
saveErrorLog(req, err);
} else {
query = {centralRecordMode: {$in: ["Payment In", "Payment Out", "Transfer", "General Out"]}, disabled: {$mod: [2, 0]}, centralRecordType: {$in: ["Split", type]}, _ExternalParty: _id, status: {$ne: "Reject"}};
CentralRecordSheet.find(query).lean().exec(function (err, centralRecordSheetObjects) {
if (err) {
saveErrorLog(req, err);
}
_.each(centralRecordSheetObjects, function (centralRecordSheetObject) {
// SOME MORE PROCESSING
});
fullCentralRecordSheetObjects = _.sortBy(fullCentralRecordSheetObjects, function (fullCentralRecordSheetObject) {
return new Date(fullCentralRecordSheetObject.centralRecordDate).getTime();
});
let runningBalance = 0;
_.each(fullCentralRecordSheetObjects, function (fullCentralRecordSheetObject) {
runningBalance = runningBalance - fullCentralRecordSheetObject.paymentIn.total + fullCentralRecordSheetObject.paymentOut.total + fullCentralRecordSheetObject.moneyIn.total - fullCentralRecordSheetObject.moneyOut.total + fullCentralRecordSheetObject.transferIn.total - fullCentralRecordSheetObject.transferOut.total;
fullCentralRecordSheetObject.balance = runningBalance;
const newFullCentralSheetRecordObject = new FullCentralRecordSheet(fullCentralRecordSheetObject);
newFullCentralSheetRecordObject.save(); // Asynchronous save
});
});
}
});
});
});
};
这是我处理一些数据并将其保存到数据库的代码。正如您所看到的,每个异步循环都涉及一些计算,循环之后会有最终的数据处理。如果我一次传入一个_id,它工作正常。但是,当我尝试像这样执行任务时
exports.refreshFullCentralRecordSheetObjects = function (req, next) {
ExternalParty.find().exec(function (err, externalPartyObjects) {
if (err) {
utils.saveErrorLog(req, err);
return next(err, null, [req.__(err.message)], []);
}
_.each(externalPartyObjects, function (externalPartyObject) {
updateFullCentralRecordSheet(req, externalPartyObject._id, "Malay");
updateFullCentralRecordSheet(req, externalPartyObject._id, "Thai");
})
return next(err, null, ["Ddd"], ["Ddd"]);
});
};
我有大约273个对象要循环。这会导致内存致命错误。我试图增加--max-old-space-size=16000
,但它仍在崩溃。我使用任务管理器来跟踪node.exe进程的内存,它超过8 GB。
我不确定为什么增加16GB的内存没有帮助,它仍然会在8GB左右崩溃(根据任务经理的说法)。另一件事是当我尝试仅处理10个记录而不是273时,任务管理器报告它使用大约500 MB。除非我向服务器发出另一个请求,否则此500 MB不会消失。我发现这很奇怪,因为在完成处理10条记录后,为什么NodeJS不会收集垃圾?这10条记录已成功处理并保存到数据库,但任务管理器中的内存使用情况保持不变。
我尝试使用async.forEachLimit,将我的更新功能变为异步,使用process.nextTick(),但我仍然有致命的错误内存问题。我该怎么做以确保这个运行?
答案 0 :(得分:0)
另一件事是我尝试只处理10条记录而不是273条记录, 任务管理器报告它使用大约500 MB。这个500 MB会 除非我向服务器发出另一个请求,否则不会消失。我找到了这个 非常奇怪,因为NodeJS完成后为什么不收集垃圾 处理10条记录?这10条记录已成功处理 并保存到数据库但是内存使用量保持不变 任务经理。
这是正常的,节点GC是懒惰的(GC是同步操作,阻塞循环,所以这是一件好事)。
尝试对查询进行分页?