Every once in a while I find myself doing something along the lines of the following
var img = new Image();
img.src = 'php/getpic.php?z=' + imid + '&th=0';
img.onload = function(){drawImages(img,contexts,sizes)};
Explanation
- Create an HTML image element.
- Assign its src attribute
- Assign its onload event
- Pass one or more Canvas contexts to the event handler
- Draw the loaded image to the canvases
The thing I am not clear about is this – will the JavaScript garbage collector deal with the task of discarding the img element or do I need to do it myself or else face a slooow memory leak?
It will leak in IE 6 and 7 (and very old versions of FF) because it creates a circular reference between JavaScript and the DOM. IE 6 and 7 can’t garbage collect any objects which have circular references between the two worlds because they use separate garbage collectors.
Modern browsers can handle this without leaking.
To prevent it from leaking in IE 6 and 7, do this when you’re done with
img:If you only care about modern browsers, you don’t have to worry about it. (I’m so glad IE 6 and 7 are finally low enough in market share to suggest that!)
Update
The function you assign to
onloadcreates a closure. That closure contains a reference toimg.imgcan’t be garbage collected from the DOM’s memory as long as that closure exists in JScript’s memory (JScript is name for the IE implementation of JavaScript). Likewise, the closure can’t be garbage collected from JScript’s memory as long asimgexists in the DOM’s memory, becauseimg.onloadhas a reference to your function. This is a circular reference. In other words, just becausedrawImagesexecutes once doesn’t mean it won’t execute again (the JScript engine doesn’t knowonloadonly fires once — that’s the DOM’s domain), so JScript has to keep the closure alive.The pattern you have shown is the classic pattern that is known to create memory leaks in IE 6 & 7. It consists of (1) A DOM node, (2) An event handler on that DOM node which creates a closure, and (3) A reference back to that DOM node inside the closure.