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
以及另外一个不值得提的场景),而且我没有发现很大的差别。
总结我有两个问题:
-
这是正常的GC行为来清除内存在一定的时间间隔,或者它达到一些threashold而不是连续清理?
-
我正确地认为,与
.on
示例代码应该泄漏内存,.on
我没有看到内存消耗图吗?
1:是的:-)
2:一般来说,使用事件侦听器时,内存的泄漏是由于正在发送的对象正在保存引用,所以正在侦听的对象被阻止被垃圾收集。
所以在你的代码中, onSuccess
函数将被你的request
对象引用。 但是, onSuccess
只是一个被重用作所有请求对象的侦听器的函数,所以不应该导致内存堆积。
旁注:我不知道redisClient
和RequestObject
的内部,但是对于我来说,只要initRequest
函数完成,也可能在调用它的任何监听器之前,它看起来像request
将准备好垃圾回收。
据我可以看到,请求对象应该只存在于initRequest函数中,因此当函数终止时应该标记为垃圾回收。