Node.js(v8)垃圾收集器如何工作?

我已经做了一些testing与我的node.js应用程序寻找内存泄漏,我的代码应该做的。 我运行的脚本,在我看来应该泄漏内存,但我感到惊讶的结果。

redisClient.on('message', initRequest); function onSuccess(self, json){ console.dir(json); } function initRequest(channel, message){ var request = new RequestObject({ redisMessage: message }); request.on('success', onSuccess); } 

redisClient每秒发出几个“消息”事件。 这意味着initRequest函数经常被调用。 每次request对象在内存中创build时,函数onSuccess绑定到它的“成功”事件。

我假设(但在这里我可能是错的),只要有监听器(在这种情况下的onSuccess )绑定到这个对象,它不能被垃圾收集。 然后我想,内存使用量将会增长,因为内存不会被释放。

作为这个潜在的泄漏的解决scheme,我想使用.once而不是.on ,因为这将解除绑定的监听器和对象可以被垃圾收集。

我用pmap来testing两种情况(比较.on.once以及另外一个不值得提的场景),而且我没有发现很大的差别。

在这里输入图像描述

总结我有两个问题:

  1. 这是正常的GC行为来清除内存在一定的时间间隔,或者它达到一些threashold而不是连续清理?

  2. 我正确地认为,与.on示例代码应该泄漏内存, .on我没有看到内存消耗图吗?

1:是的:-)

2:一般来说,使用事件侦听器时,内存的泄漏是由于正在发送的对象正在保存引用,所以正在侦听的对象被阻止被垃圾收集。

所以在你的代码中, onSuccess函数将被你的request对象引用。 但是, onSuccess只是一个被重用作所有请求对象的侦听器的函数,所以不应该导致内存堆积。

旁注:我不知道redisClientRequestObject的内部,但是对于我来说,只要initRequest函数完成,也可能在调用它的任何监听器之前,它看起来像request将准备好垃圾回收。

据我可以看到,请求对象应该只存在于initRequest函数中,因此当函数终止时应该标记为垃圾回收。