Why does this use of getImageData leak memory

Issue

I would like to do some image processing with Dart while using requestAnimationFrame to continually update the image I am processing. The following code will leak memory until the tab crashes in Dartium.

import 'dart:html';
import 'dart:async';

final CanvasElement m_canvas = querySelector("#canvas");

void main() {
  scheduleMicrotask(requestRedraw);
}

void requestRedraw() {
  if(true)
  {
    window.requestAnimationFrame(draw);
  }
}

void draw(num _) {
  var context = m_canvas.context2D;
  context.clearRect(0, 0, m_canvas.width, m_canvas.height);
  var imageData = context.getImageData(0, 0, m_canvas.width, m_canvas.height);
  requestRedraw();
}

The imageData var is clearly going out of scope with after each draw call completes yet the memory that it retains is never released. Commenting out this line results in the code running fine, updating at 60 fps. Is this memory leak a bug in the current dart implementation or am I doing something wrong?

Solution

It is very weird but when I add a print() statement to your code the GC kicks in (at least in Dartium)

int i = 0;
void draw(num _) {
  var context = m_canvas.context2D;
  context.clearRect(0, 0, m_canvas.width, m_canvas.height);
  var imageData = context.getImageData(0, 0, m_canvas.width, m_canvas.height);
  print(i++);
  requestRedraw();
}

Answered By – Günter Zöchbauer

Answer Checked By – Marilyn (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.