[SOLVED] Memory leak using Canvas context2d.getImageData
-
Consider the following minimal example (not very useful, but it serves to expose the problem):
Timer { interval: 500; running: true; repeat: true onTriggered: canvas.requestPaint() } Canvas { id: canvas property var imageData onPaint: { var ctx = canvas.getContext("2d"); if (canvas.imageData) { // if we have image data from a previous paint, draw it translated 10px up. ctx.drawImage(canvas.imageData, 0, -10); } // draw something on ctx // save the image data of the ctx on canvas.imageData, for using that in the following paint canvas.imageData = ctx.getImageData(0, 0, canvas.width, canvas.height) // this causes a memory leak } }
A Timer force a Canvas paint every 500ms. In every paint (except the first) I want to redraw the previous image of the canvas, translated by 10px up, then draw something on the canvas, and then save the image for the next paint.
The code works as expected, but I have a memory leak when calling ctx.getImageData.
I assumed that replacing canvas.imageData with a new call to ctx.getImageData would have garbage collected the old canvas.imageData, but this is not the case.I tried adding
delete canvas.imageData.data delete canvas.imageData
After drawing the image in every paint cycle, I have no errors, but it doesn't solve the memleak.
What I'm doing wrong here? Is there a workaround?
Thank you very much for your help!
-
Solved thank to the help of inz on IRC.
I've added the line
gc()
just after the line
canvas.imageData = ctx.getImageData(0, 0, canvas.width, canvas.height) // this causes a memory leak
And the memleak disappeared. Seems like the automatic garbage collector didn't run often enough for my use case, so the call to gc() is necessary to force the garbage collection.