Mongoose / Nodejsvalidationerror handling,内存泄漏问题

我遇到了一种情况,即在创buildmongoose对象时,nodejs似乎正在泄漏内存,但由于validation错误而失败。 对我来说这似乎很奇怪,我正在寻求社区的帮助。

在我试图重新创build我的问题的示例代码中,我有一个非常简单的Mongoose模型,它validation其中一个字段是非负数。 反复尝试创build无效对象(在下面的代码中, XVALUE-1 ),我看到内存永远在增长。 但有效的对象(以XVALUE+1 ,如所说)按预期工作,没有任何泄漏。 我正在使用process.memoryUsage().heapUsedvariables跟踪内存。

当尝试创build无效对象时,如何摆脱内存泄漏? 如果我不正确地使用mongoose,任何改善使用的build议将不胜感激。

版本: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); 

发生的事情是,如果文档无效,则x.saveasynchronous操作立即完成,只要其父项addEntry函数调用完成,就立即调用它的callback函数。 这不会让垃圾收集运行,并且内存使用量不断增长。

为了解决这个问题,把recursion的addEntry调用放到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++; }); };