1

Lets get right to the code:

function drawImg(img) {                       
    var image = new Image();
    image.onload = function() {                                     
        context.drawImage(image, 0, 0);
    }; 
    image.src = img; 
}; 

This is a pretty common basic implementation of drawing an image to an html5 canvas context.

The value passed to the drawImg function: img, is a base64 string like

"data:image/png;base64,somebase64stuffhere...."

Now let us say that drawImg is being called 15 times per second (15fps) and that the size of the base64 encoded img is 20-30k.

FireFox and Internet Explorer's 10,11 perform well enough. GC and memory spiking on FF get a little wild but it's within acceptable ranges. Earlier versions of IE, and most depressingly, chrome, fail to manage the memory allocation of, assuming, the Image object, and in short order will consume all the memory available and crash.

  • I've commented out the canvas portion of this code.
  • I've commented out the entire section of code to check against memory leaks outside of the drawImg function.
  • My conclusion is that, the image, image.onload, image.src code bits are causing the crashing memory growth.
  • Similar questions here on SO confirm this thought, however I haven't been able to validate any of the solutions for my particular case.

So my question: How can I best implement this without running up memory in some browsers?

Caveats:

  • I'd prefer not to stray to far from the concept of getting a base64 string, at no point am I writing to a filesystem and prefer to keep it that way.
  • I do not have the liberty of simply refreshing the page.
6
  • i found MUCH lower memory use in something similar, saving canvas history snapshots. using dataURL, ram went through the roof, but when i instead tried simply cloning the painted canvas elements and hiding the old ones instead, everything went super fast again. you can probably just cycle a pool image tags much faster than you can pump base64 data around, and then there's not image decoding, etc... Commented Jan 24, 2014 at 18:35
  • why are you loading the image each time you want to draw it? Just load it once in global or parent scope and reuse it. Commented Jan 24, 2014 at 18:35
  • @ken the image data is different every frame, I have loaded var image in the global scope, it seems to make marginal difference. Most of my research points to some browsers being unable to dereference the src when it changes so rapidly. Commented Jan 24, 2014 at 18:41
  • @dandavis thanks, I was trying to think of a way to implement dataURL but maybe I'll just avoid that now. I only have base64 data to play with, it's being pushed to the browser from a remote location via websockets. Note, already ruled out websocket connection and transfer as the source of the leak it is most definitely in that image.src. Commented Jan 24, 2014 at 18:46
  • @tremor are the images unique 15*∞? watch this example which may be WAY different to what you are doing but may spark some ideas: jsfiddle.net/helmutgranda/d2W7D Commented Jan 24, 2014 at 18:54

1 Answer 1

1

It seem to be a know issue in Chrome:

https://code.google.com/p/chromium/issues/detail?id=309543

There'll still be growth observed in the TC, but most of that should be due to GC heuristics, so will be collected eventually, keeping memory usage bounded.

And as of Jan 21:

Latest dev should have it [fix] by now. (34.0.1788.0 I think)

Version 34 is currently Canary.

Sign up to request clarification or add additional context in comments.

1 Comment

This might be it with Chrome, I'll need to re-test the elder versions of IE with the change of my image tag to the global scope as suggested in the comments. My current Chrome is 32 so I'll get on the dev channel and try that out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.