During testing of our Javascript library I think we found a severe memory leak in IE10's (v10.0.9200.16519 - Windows 8 64 bit) Javascript implementation of setInterval
.
A simple test case showed that if a variable is captured in the closure of the function being passed as the argument for later execution it does not seem to ever become eligible for garbage collection, i.e. the browser still seems to hold a reference to the function or at least the closure variables.
Our testcase executes the setInterval
function only once and then clears the interval timer, i.e. after a while no code is running anymore and no variables are accessible anymore (as far as I can see no globals are introduced in this code, except for the method to run in onload
), nevertheless the process takes up half a gigabyte of memory (depending on the number of iterations).
Interestingly this does not happen if we use the setTimeout
method instead (and also the problem does not seem to exist in IE9, and current versions of Chrome, FF).
The problem can be seen with this fiddle.
Run it in a fresh instance of IE10 on Windows 8 and open the task manager to watch the memory usage. It will grow quickly to 350 Megabytes and will stay there after the script was executed.
This is the important part of the problematic code piece:
// the function that when called multiple times will cause the leak in IE10
var eatMemory = function() {
var a = null; // the captured closure variable
var intervalId = setInterval(function() {
a = createBigArray(); // call a method that allocates a lot of memory
clearInterval(intervalId); // stop the interval timer
}, 100);
}
(I know that it is easy to fix this specific piece of code. But that's not the point - this is just the tiniest piece of code we came up with that reproduces the problem. The real code actually captures this
in the closure and that object is never garbage collected.)
Is there a bug in our code or is there a way to use setInterval
where a closure variable holds a reference to a large object without triggering the memory leak and without reverting to "recursive" setTimeout
calls?
(I also posted the question on MSDN)
Update: This issue also exists in IE10 on Windows 7, but does not exist if you switch to IE9-standards mode. I submitted this to MS Connect and will report progress.
Update: Microsoft accepted the issue and reported it to be fixed in IE11 (preview version) - I haven't confirmed this myself, yet (anybody?)
Update: IE 11 has been officially released and I cannot reproduce the problem on that version with my system (Win 8.1 Pro 64bit) anymore.