8

Supposed I have a simple http server such as:

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);

So, basically the default 101 sample, nothing special so far - except that I subscribe to the data and the end event of the readable req stream. Now I wonder whether I have to unsubscribe those events when I no longer need them?

Or are they cleared automatically when the readable stream ends?

Could code like this cause a memory leak?

2
  • 3
    This might be helpful. Commented Oct 23, 2013 at 19:25
  • That was actually helpful in a more common sense. Thanks :-) Commented Oct 23, 2013 at 19:29

1 Answer 1

17
+250

(This answer contains links to the revelant parts of the node.js source code)

Before answering your question, let's talk about events. When you do this:

emitter.on('an-event', listener);

listener gets added to a list attached to emitter. Later, when emitter triggers the event, it notifies all the listeners subscribed to the event by iterating through the list. The magic of node.js event emitters is that you don't declare or manage that list yourself.

However, whenever you call .on(), you create a back-reference emitter -> listener. This reference will prevent the listener from being collected by the GC and create a "leak" if you never unsubscribe.

This does not happen very often with node.js, because usually, emitters are destroyed before listeners, but a real-world case where this happens is when you have a long running connection (think Twitter Streaming API) that sometimes reconnects. If you don't unregister events, you might get events from the old connection and think they apply to the new one. This can lead you to think the new connection has closed.

node.js will print the infamous "possible leak detected" message when it thinks you might be forgetting to unregister listeners.

Back to your example:

This won't create a leak because the socket (req+res) will be destroyed first. Since it's the emitter, node.js will forcibly remove all listeners.

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent answer, thanks a lot, especially for the part with when emitters get destroyed. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.