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.
To sum up I have 2 questions:
Is this normal GC behavior to clean memory in some intervals, or after it reach some threshold instead of continuous cleaning?
Am I correctly assume that example code with .on
should leak memory, which I don't see on memory consumption graph?
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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With