| TL;DR -- all closures created within a function are retained even if only one closure is ever referenced. This is really interesting, and potentially devastating for certain coding styles. I ran the code on node and the RSS does appear to be increasing without bound. Even running node with --expose-gc and forcing a global.gc() inside logIt() causes the same unbounded memory growth. Increasing the size of the array by a factor of 10 causes RSS usage to jump up by a factor of 10 every second, so we know that the memory usage isn't caused by creating a new long-lived closure (i.e., the logIt() function) every second. In fact, removing the call to doSomethingWithStr() doesn't change the unbounded memory growth. Here's a shorter snippet that demonstrates the leak more dramatically (about 10 MB/sec RSS growth): var run = function () {
var str = new Array(10000000).join('*');
var fn = function() {
str;
}
var fn = function() { }
setInterval(fn, 100);
};
setInterval(run, 1000);
Tried it out on node v0.8.18 |