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를 전달하면 잘 작동합니다. 그러나이 작업을하려고 할 때NodeJS 비동기 함수를 사용한 for 루프를 사용하는 메모리가 부족합니다.
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
을 늘리려고했지만 여전히 충돌하고 있습니다. 나는 task manager를 사용하여 node.exe 프로세스의 메모리를 추적하고 8GB 이상이됩니다.
메모리를 16GB로 늘리는 것이 도움이되지 않는 이유는 확실하지 않지만, 작업 관리자에 따르면 여전히 약 8GB가 충돌합니다. 또 다른 것은 273 개가 아닌 10 개의 레코드 만 처리하려고 할 때 약 500 MB를 사용하는 작업 관리자 보고서입니다. 이 500MB는 서버에 다른 요청을하지 않으면 사라지지 않습니다. 왜 NodeJS 쓰레기 수집 후 10 레코드를 처리 할 수 없기 때문에이 매우 이상한 찾으십시오? 10 개의 레코드가 성공적으로 처리되어 데이터베이스에 저장되었지만 메모리 사용량은 작업 관리자에서 변경되지 않았습니다.
async.forEachLimit을 사용하여 내 업데이트 기능을 비동기로 돌리려고 시도했지만 process.nextTick()으로 재생했지만 여전히 치명적인 오류 메모리 문제가 있습니다. 이 프로그램이 실행되도록하려면 어떻게해야합니까?
'async.each (profitLossSheetObjects, ...'?) 대신에 async.eachLimit (profitLossSheetObjects, ...'를 사용 해보려고 했습니까? – cartant
예 모두 했어요! – Zanko