I'm using getImageData
/putImageData
on a HTML5 canvas to be able to manipulate a picture.
My problem is that the browser never seems to free any memory. Not until I close the tab (tested in Chrome and Opera).
Moved these out of the function:
var ctx = document.getElementById('leif').getContext('2d'); var imgd = ctx.getImageData(0,0,width,height); var pix = imgd.data; var rndpixel = 0;
and the problem disappeared!
function infiniteLeif()
{
for (var i = 0; i<65536; i+=4) {
rndpixel=Math.floor(Math.random()*(width*(height-2))+width+4) * 4;
pix[rndpixel-wx4] = pix[rndpixel]; pix[rndpixel-wx4+1] = pix[rndpixel+1]; pix[rndpixel-wx4+2] = pix[rndpixel+2];
pix[rndpixel+wx4] = pix[rndpixel]; pix[rndpixel+wx4+1] = pix[rndpixel+1]; pix[rndpixel+wx4+2] = pix[rndpixel+2];
pix[rndpixel-4] = pix[rndpixel]; pix[rndpixel-4+1] = pix[rndpixel+1]; pix[rndpixel-4+2] = pix[rndpixel+2];
pix[rndpixel+4] = pix[rndpixel]; pix[rndpixel+4+1] = pix[rndpixel+1]; pix[rndpixel+4+2] = pix[rndpixel+2];
}
ctx.putImageData(imgd,0,0);
if (go==1) t=setTimeout(infiniteLeif,40);
}
A full example can be found here (Google Chrome is recommended).
It's not the setTimeout
that is the problem because I tried a loop with the same effect.
I've come to understand that removal of circular references often is the key but do I really have one? How can I change this code so that the JavaScript GC gets a chance to do it's job?
It won't help, possibly with your leak, but you are reloading an array every 40ms with data that hasn't changed.
You may want to use a closure around the initialization.
Basically, just create a variable that has the function with the loop, with the pix info enclosed within it.
Then, you just continue to recursively call where you don't reinitialize, but just use the variable with the loop.
This way you reuse the same pix info, it maintains it's state, which should be fine, unless you edit the canvas elsewhere.