JavaScript can leak memory, if you define a function inside a forEach loop:
an example of the 'antipattern' is:
Note: this issue may be made worse, by use of jQuery bind() - however I have not fully tested this.
note: jQuery bind() uses 'on' to add an event handler. This involves creating a temporary function - and so it is probably best to avoid calling bind() in any kind of loop.
ref: http://james.padolsey.com/jquery/#v=1.8.3&fn=jQuery.fn.on
Explanation:
Here is my explanation - hope to improve it:
In Chrome, there is an optimisation, so that it only creats 1 definition of the function inside the forEach.
However, Chrome still has to have some kind of pointer object for each iteration of the forEach loop.
This means that if there are many iterations, then a large number of small objects are created.
The objects should be cleaned up over time, when they are no longer reachable on the GC graph.
However, having lots of temporary objects is never a good idea, as it gives the GC more work to do, and the GC only has a small timeslice in which to operate. Note: Chrome uses a 'stop the world' GC which means it must have a very very small timeslice!
In IE10, the memory leak is much worse, which is probably because IE10's JavaScript engine is inferior to Chrome. You can compare JavaScript engine performance here:
http://octane-benchmark.googlecode.com/svn/latest/index.html
Further Reading:
Writing Garbage Collector friendly code:
http://buildnewgames.com/garbage-collector-friendly-code/
Leak finder for JavaScript:
(seems to only work if your project uses Closure library)
https://code.google.com/p/leak-finder-for-javascript/
Writing Fast Memory Efficient Javascript:
http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/
an example of the 'antipattern' is:
var myObjects = ['a', 'b', 'c'];
myObjects.forEach(function (obj) {
//do work here ...
});
Note: this issue may be made worse, by use of jQuery bind() - however I have not fully tested this.
var myObjects = ['a', 'b', 'c'];
myObjects.forEach(function (obj) {
//do work here ...
}.bind(this));
note: jQuery bind() uses 'on' to add an event handler. This involves creating a temporary function - and so it is probably best to avoid calling bind() in any kind of loop.
ref: http://james.padolsey.com/jquery/#v=1.8.3&fn=jQuery.fn.on
Explanation:
Here is my explanation - hope to improve it:
In Chrome, there is an optimisation, so that it only creats 1 definition of the function inside the forEach.
However, Chrome still has to have some kind of pointer object for each iteration of the forEach loop.
This means that if there are many iterations, then a large number of small objects are created.
The objects should be cleaned up over time, when they are no longer reachable on the GC graph.
However, having lots of temporary objects is never a good idea, as it gives the GC more work to do, and the GC only has a small timeslice in which to operate. Note: Chrome uses a 'stop the world' GC which means it must have a very very small timeslice!
In IE10, the memory leak is much worse, which is probably because IE10's JavaScript engine is inferior to Chrome. You can compare JavaScript engine performance here:
http://octane-benchmark.googlecode.com/svn/latest/index.html
Further Reading:
Writing Garbage Collector friendly code:
http://buildnewgames.com/garbage-collector-friendly-code/
Leak finder for JavaScript:
(seems to only work if your project uses Closure library)
https://code.google.com/p/leak-finder-for-javascript/
Writing Fast Memory Efficient Javascript:
http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/
Gmail – how they find and fix JavaScript memory leaks:
Comments
Post a Comment