假设我有一个简单的 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
被添加到 list附加到 emitter
。稍后,当 emitter
触发事件时,它会通过遍历列表来通知所有订阅该事件的监听器。 node.js 事件发射器的神奇之处在于您无需自己声明或管理该列表。
但是,无论何时调用 .on()
,都会创建一个 back-reference发射器 -> 听众。如果您从不取消订阅,此引用将阻止监听器被 GC 收集并造成“泄漏”。
这种情况在 node.js 中并不经常发生,因为通常情况下,发射器会在监听器之前被销毁,但发生这种情况的真实情况是当您有一个长时间运行的连接(想想 Twitter Streaming API),有时会重新连接。如果您不注销事件,您可能会从旧连接获取事件并认为它们适用于新连接。这可能会让您认为新连接已关闭。
node.js 会打印臭名昭著的 "possible leak detected"当它认为您可能忘记注销听众时发送消息。
回到你的例子:
这不会造成泄漏,因为套接字 (req+res) 将首先被销毁。由于它是发射器,node.js 将 forcibly remove all listeners .
关于node.js - 在 Node.js 中使用流时内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19550180/