假设我有一个简单的http服务器,例如:
var http = require('http');
http.createServer(function (req, res) {
req.on('data', function (data) {
console.log('Got some data: ' + data);
});
req.on('end', function () {
console.log('Request ended!');
});
res.end('Hello world!');
}).listen(3000);
因此,基本上是默认的101示例,到目前为止没有什么特别的-除了我订阅了可读流的data
和end
事件req
。现在我想知道当我不再需要这些事件时是否必须取消订阅这些事件?
还是在可读流结束时自动清除它们?
这样的代码会导致内存泄漏吗?
(此答案包含指向node.js源代码的相关部分的链接)
在回答您的问题之前,让我们谈谈事件。执行此操作时:
emitter.on('an-event', listener);
listener
被添加到附加到的列表中emitter
。稍后,当emitter
触发事件时,它将通过遍历列表来通知所有订阅该事件的侦听器。node.js事件发射器的神奇之处在于,您不必自己声明或管理该列表。
但是,无论何时调用.on()
,都将创建向后引用发射器->侦听器。此参考将防止GC收集侦听器,并且如果您永不退订,则会创建“泄漏”。
对于node.js,这种情况并不经常发生,因为通常,发射器会在侦听器之前被破坏,但是在现实情况中,这种情况是当您具有长时间运行的连接(例如Twitter Streaming API)时,有时会重新连接。如果不注销事件,则可能会从旧连接中获取事件,并认为它们适用于新连接。这可能会导致您认为新连接已关闭。
当它认为您可能忘记注销注册侦听器时,node.js将显示臭名昭著的“检测到可能的泄漏”消息。
回到您的示例:
因为不会先泄漏套接字(req + res),所以不会造成泄漏。由于它是发射器,所以node.js将强制删除所有侦听器。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句