读取Node.js堆快照(通过Nodetime创建)——为什么我的对象不是GC';D

读取Node.js堆快照(通过Nodetime创建)——为什么我的对象不是GC';D,node.js,Node.js,我的Nodetime堆快照中有一些令人惊讶的结果: 我的堆中有1706个“用户”实例,我读对了吗?这似乎高得离谱,我甚至不太确定我该如何分配这么多。在任何情况下,是否有任何提示/诀窍/提示来找出这些问题的原因?我已经在我的代码中使用了JSHint来确保没有分配免费的全局变量。所有内容都应包装在请求的关闭范围内。。。那么,当请求完成时,为什么用户、帖子等没有被垃圾收集呢?这里有一些(编辑过的)代码来显示我是如何做事情的 非常令人惊讶的是,我在上一次API调用完成后大约10米拍摄了上面的堆快照。因

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

我的堆中有1706个“用户”实例,我读对了吗?这似乎高得离谱,我甚至不太确定我该如何分配这么多。在任何情况下,是否有任何提示/诀窍/提示来找出这些问题的原因?我已经在我的代码中使用了JSHint来确保没有分配免费的全局变量。所有内容都应包装在请求的关闭范围内。。。那么,当请求完成时,为什么用户、帖子等没有被垃圾收集呢?这里有一些(编辑过的)代码来显示我是如何做事情的

非常令人惊讶的是,我在上一次API调用完成后大约10米拍摄了上面的堆快照。因此,在触发分配这些对象的请求完成后,这些对象都会挂起很长时间

代码:

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

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
});

根据上面的express代码,我希望分配给用户对象的生命周期仅与请求返回所需的时间相同。我是不是遗漏了一些关键的Node.js GC想法?

这行代码看起来效率很低:

var user = extend({},User).initialize();
我假设
extend
调用复制
User
对象,然后调用其
initialize
方法。为什么要在每次API调用上复制
User
对象

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


这两者的结合可能会导致每次调用时创建的对象比需要的多,我打赌那些注册的Mongoose模型不容易GC。

.then(function(data){user=null;res.writeHead(200,{});
您可以将对象设置为null来清除它们。(按下shift enter键时,sry按下enter键)这在某种程度上是有道理的…但不是节点/javascript等的重点。为了避免这种手动级别的内存管理…?检查节点的每一行并在处理完所有对象后将其置为空似乎是一种不太可能的奇怪解决方案。因为在堆快照中看到“user”属性意味着“user”和“posts”属性re在堆中,即是对象的一部分,而不是闭包范围变量。这可能会提示您可能泄漏的内容。您是否看到“user”或“posts”属性计数与数据库中的用户、调用等有任何关联?对象不在闭包范围内,只有保留符(例如变量)可以。如果闭包超出范围,则对象将失去引用并将被GC'd,除非没有其他引用。在您的情况下,它们似乎是在其他地方引用的。对象的数量是否只是随着时间的推移而增加?嗯,我想我不理解“范围外的关闭”这一概念无论如何,我只是做了一些快速测试:我启动了服务器,然后对节点服务器进行了一次API调用。“posts”属性的计数为9,大小为1350Kb。刷新同一个API调用几次后,大小发生了变化,但计数保持不变。通常,这些对象(用户、帖子等)上的计数是相同的似乎有波动,但没有超过某个数字……我也不喜欢这种方法,但我从这个网站上得到了它:不过,关于模型的观点很好。@ZaneClaes你在这里误用了
extend
概念,因为你没有向
User
添加任何方法或属性,你只是在复制它并增加开销。嗯,在在“User”类中省略的函数,我需要存储实例特定的数据。例如,this.data='mydata';在一个省略的函数中。换句话说,我试图实例化User类的一个实例,但是new User().initialize();不起作用:(不过,当我回顾这篇文章时,很明显我做错了什么……我只是不知道如何做对
var user = extend({},User).initialize();