我遇到的情况是,当尝试创建mongoose对象时,nodejs似乎在泄漏内存,但由于验证错误而失败。这对我来说似乎很奇怪,我正在寻求社区的帮助来深入了解它。
在我尝试重新创建问题的示例代码中,我有一个非常简单的Mongoose模型,它将其中一个字段验证为非负数。在下面的代码中反复尝试创建无效对象(XVALUE
为-1
),我看到内存永远在增长。但有效的对象(XVALUE
为+1
)可以正常工作,没有任何泄漏。我正在使用process.memoryUsage().heapUsed
变量跟踪内存。
如果尝试创建无效对象,如何摆脱内存泄漏?如果我错误地使用猫鼬,我们将非常感谢任何有关改善使用情况的建议。
版本:mongoose - 3.8.x和nodejs - 0.10.x。
以下是我用来重新创建问题的示例代码:
(function() {
var MAX_ITER_COUNT, MyModel, MyStuff, Schema, XVALUE, addEntry, conn, iterCount, mongoose;
mongoose = require("mongoose");
conn = mongoose.createConnection('mongodb://@127.0.0.1:27017/memtest');
conn.on("error", function(err) {
return console.error(err);
});
Schema = mongoose.Schema;
MyStuff = new Schema({
x: {
type: Number
}
});
XVALUE = -1;
MyStuff.path("x").validate((function(val) {
if (val < 0) {
return false;
}
return true;
}));
MyModel = conn.model("MyStuff", MyStuff, "stuff");
iterCount = 0;
MAX_ITER_COUNT = 100 * 1000;
addEntry = function() {
var currentMem, x;
currentMem = Math.round(process.memoryUsage().heapUsed / 1024 / 1024);
console.log("" + iterCount + " - memory is: " + currentMem + " MB");
x = new MyModel({
x: XVALUE
});
return x.save(function(err) {
if (err) {
console.log("" + iterCount + " - failed");
} else {
console.log("" + iterCount + " - Save successful");
}
if (iterCount < MAX_ITER_COUNT) {
addEntry();
}
return iterCount++;
});
};
conn.on("open", addEntry);
}).call(this);
答案 0 :(得分:2)
发生的事情是,如果文档无效,x.save
异步操作立即完成,一旦其父addEntry
函数调用完成就调用其回调。这使得垃圾收集无法运行,内存使用量也在不断增长。
要解决此问题,请在对setImmediate
的调用中添加递归addEntry
调用,以便GC有机会在迭代之间运行:
addEntry = function() {
var currentMem, x;
currentMem = Math.round(process.memoryUsage().heapUsed / 1024 / 1024);
console.log("" + iterCount + " - memory is: " + currentMem + " MB");
x = new MyModel({
x: XVALUE
});
return x.save(function(err) {
if (err) {
console.log("" + iterCount + " - failed");
} else {
console.log("" + iterCount + " - Save successful");
}
if (iterCount < MAX_ITER_COUNT) {
setImmediate(addEntry);
}
return iterCount++;
});
};