读取Node.js堆快照(通过NodeTime创build) – 为什么我的对象不GC'd?

我在NodeTime堆快照中有一些令人惊讶的结果:

在这里输入图像描述

我读这个权利,有一个“用户”在我的堆1706实例? 这似乎是荒谬的高,我甚至不太确定我将如何分配这么多。 在任何情况下,有没有任何提示/技巧/提示,以找出为什么这些悬而未决? 我已经在我的代码上使用了JSHint,以确保没有可用的全局variables被分配。 一切都应该被封装在请求的封闭范围内…为什么当请求结束时,用户,post等等被垃圾收集? 这里有一些(编辑)的代码来显示我如何做事情…

非常令人惊讶的是, 在最后一次API调用完成之后我拿了上面的堆快照约10米 。 所以,那些触发他们分配的请求完成后,这些对象都是长时间悬挂的!

码:

var User = require('./user').User, Q = require('q'); // this function is called via express' router, eg when the client visits myapi.com/users/zane function getUser(req, res, next) { var user = extend({},User).initialize(); Q.ncall(user.model.find, user.model, {'username': req.arguments[0]}) .then(function(data){ res.writeHead(200, {}); res.end(JSON.stringify(data)); }) .fail(next).end(); } 

而“用户”模块看起来像这样:

 exports.User = extend({}, { initialize: function() { var Schema = api.mongoose.Schema; this.schema = new Schema({ 'username': {'type':String, 'index':true} }); this.model = api.db.model('users', this.schema); } // ... some other helper functions in here }); 

根据我上面的expression代码,我希望分配的用户对象的生命周期只要请求返回。 我在这里错过了一些关键的Node.js GC主意吗?

这条线看起来可疑低效:

 var user = extend({},User).initialize(); 

我假设extend调用复制User对象,然后调用其initialize方法。 为什么在每个API调用中复制User对象?

然后在initialize调用中,创build一个新的Mongoose模式对象,然后通过api.db.model调用将其注册为模型。 在初始化过程中创build模式并注册它不是更好吗?

这两者的结合可能导致在每次调用中创build的对象数量超过必要的数量,我敢打赌,这些注册的Mongoose模型不容易GC。