Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the Node.js (v8) Garbage Collector work?

I've done some tests with my node.js application looking for memory leak that my code supposed to do. I run script that in my opinion should leak memory, but I am surprised by the result.

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 emits a couple of 'message' events per second. This mean that initRequest function is called quite often. Each time request object is created in memory, and function onSuccess is bind to its 'success' event.

I assumed (but here I may be wrong), that as far as there is listener (onSuccess in this case) bind to this object it cannot be garbage collected. Then I thought, memory usage will grow since memory won't be free-ed up.

As a solution for this potential leak I wanted to use .once instead of .on, as this will unbind listener and object could be garbage collected.

I've used pmap to test both scenarios (comparing .on and .once and one another scenario that is not worth to mention here), and I haven't found a big difference.

enter image description here

To sum up I have 2 questions:

  1. Is this normal GC behavior to clean memory in some intervals, or after it reach some threshold instead of continuous cleaning?

  2. Am I correctly assume that example code with .on should leak memory, which I don't see on memory consumption graph?

like image 853
Kamil Z Avatar asked Jan 16 '14 13:01

Kamil Z


People also ask

How does V8 garbage collection work?

The garbage collection process only starts when a new object comes in and find no more place for it in the from-space. Then it traverses a old-to new root set to figure out whether the object is still alive and whether it has been survived from the last round. If the object is no longer used, leave it there.

How does node JS garbage collection work?

The Concept of the Garbage Collector Garbage collection is a way of managing application memory automatically. The job of the garbage collector (GC) is to reclaim memory occupied by unused objects (garbage). It was first used in LISP in 1959, invented by John McCarthy.

How does JavaScript garbage collector work?

The garbage collector takes roots and “marks” (remembers) them. Then it visits and “marks” all references from them. Then it visits marked objects and marks their references. All visited objects are remembered, so as not to visit the same object twice in the future.

Does V8 have garbage collection?

Google's V8 JavaScript engine is a runtime environment that translates JavaScript to machine code and implements garbage collection. The engine is used, as an autonomous system or module, in projects such as: the Chrome web browser and Node. js with multi-platform support.


2 Answers

1: yes :-)

2: In general the leaking of memory when using event listeners is that the object that is listening is prevented from being garbage collected because the object that is emitting is keeping a reference to it.

So in your code the onSuccess function will be referenced by your request object. However, that onSuccess is only one function that is being reused as a listener for all request objects so that should not lead to memory buildup.

Sidenote: I don't know the innards of redisClient and RequestObject but to me it also looks like the request will be ready for garbage collection as soon as the initRequest function completes, that is possibly before any of its listeners are called.

like image 158
Simon Groenewolt Avatar answered Sep 27 '22 21:09

Simon Groenewolt


As far as i can see the request object should only exists within the initRequest function, and should therefor be marked for garbage collection when the function terminates.

like image 21
Andreas Møller Avatar answered Sep 27 '22 21:09

Andreas Møller