了解Node.js驻留集大小与堆大小(OOM错误)

时间:2012-11-28 20:16:12

标签: node.js

我正在解决我的节点服务器中的一个问题,我收到导致节点应用程序崩溃的错误:

FATAL ERROR: JS Allocation failed - process out of memory

我正在使用nodetime来查看内存使用情况。我想也许我正在缩小这个问题,但我仍然很困惑。看看这个函数,它使用Mongoose从MongoDB加载一个缓存的对象:

StreamCache.prototype.loadCachedStream = function(_id, callback)
{
    this.model.findOne({'_id': _id}, {'objects':1,'last_updated':1}, function(err, d){
        callback(err, d ? d.toObject() : null);
        //The toObject() seems to cause the RSS to move into heap...?
    });
};

注意注释行。在昨晚11点之前,这条线只是

callback(err,d);

昨晚11点我添加了toObject()调用。

现在看看我的记忆图表:

enter image description here

请注意,在此更改之前,RSS增长但不是堆。更改后,堆和RSS增长完全相同(直到应用程序崩溃)。请注意,在更改之前和之后都发生了内存不足错误(上面)。但是,这种变化似乎使得堆大小在泄漏中与RSS大小相关,而在大小之前,堆大小是平的(ish)。

我的假设是,由于某种原因,这意味着toObject()函数将泄露的数据从RSS移动到堆中,因此不仅RSS泄漏而且堆也崩溃。

这听起来不错吗?

如果是这样......任何可能导致问题的想法?

1 个答案:

答案 0 :(得分:0)

我认为Heap / RSS相关性与您遇到的内存不足问题无关。

(两者之间有什么区别呢?,一个是使用的虚拟内存总量,另一个是目前物理RAM中的内容,在这种情况下它只是意味着更改引入了OS的数据结构( OS)已决定保留在物理RAM中很重要,例如因为它们经常被访问)

你所说的问题的原因是在d.toJSON()调用中,为什么你认为单独的toJSON()不会导致内存不足错误?

如果“d”对象如此巨大,说它是大对象树的根,当它被反序列化为JSON字符串时会占用所有内存,该怎么办?