node.js - Mongoose/Nodejs 验证错误处理、内存泄漏问题

标签 node.js mongoose

我遇到了一种情况,当尝试创建 mongoose 对象时,nodejs 似乎正在泄漏内存,但由于验证错误而失败。这对我来说似乎很奇怪,我正在寻求社区的帮助来查明真相。

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

当尝试创建无效对象时,如何消除内存泄漏?如果我错误地使用 mongoose,任何有关改进用法的建议将不胜感激。

版本: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.save 异步操作会立即完成,并在其父 addEntry 函数调用完成后立即调用其回调。这使得垃圾收集没有机会运行,并且内存使用量不断增加。

要解决此问题,请将递归 addEntry 调用放在对 setImmediate 的调用中。让 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++;
  });
};

关于node.js - Mongoose/Nodejs 验证错误处理、内存泄漏问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27006926/

相关文章:

node.js - 与僧侣的数据库连接错误处理

javascript - Nodejs + Socket.IO - 如何在套接字关闭后获取传输的总字节数(读/写)

javascript - stub 不返回 proxyquire 中的解析数据变得未定义

node.js - NodeJS + PostgreSQL 集成测试

node.js - Express 4 空 JSON 查询

MongoDB:如何通过子文档 ID 查找?

javascript - 找到 Mongoose 文档,然后按不同层进行随机排序?

node.js - 合并聚合并在 MongoDB 中查找结果

javascript - 查找和更新嵌套级别

javascript - 当用 sinon.js stub Mongoose 时,为什么我得到 "TypeError: Cannot read property ' 恢复'未定义'