5

I have a websocket that sends binary images. My script get those images, convert to base64 and display in a tag.

Something like this:

websocket.onmessage = function(evt) {
    var msg = evt.data;

    var image = $('.my-image')
    image.attr('src', "data:image/jpeg;base64,"+ toBase64(msg))
}

This seems to cause a memory leak in Chrome. After a few minutes, it will be easily using more than 1GB of RAM. In a few hours I get the "Aw, Snap" error.

Looking at the resources tab, I see that all images received are displayed. It doesn't look like they are removed at any moment, even when they aren't displayed anymore.

Is there a workaround to this issue? Maybe a way to force the old images to be removed from memory.

Fernando
  • 4,459
  • 4
  • 26
  • 39

2 Answers2

0

I had been plagued by the same issue, with rising memory usage in the browser. Turns out this is not a memory leak, but instead a side-effect of the browser caching images.

@metal03326 provides a solution at https://stackoverflow.com/a/38788279/1510289. The idea is to,

  1. write the image bytes to a JavaScript Blob,
  2. create a unique object URL from the blob,
  3. use the unique object URL in your src attribute, and finally
  4. revoke the object URL when done to release memory.

Here's the code:

function getBlob(byteString, mimeString) {
  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }
  var blob = new Blob([ab], {type: mimeString});
  return blob;
}

let prevObjectURL = null;

websocket.onmessage = function(event) {
  var blob = getBlob(atob(event.image), 'image/jpg');
  var objectURL = URL.createObjectURL(blob);
  $('.my-image').attr('src', objectURL);
  URL.revokeObjectURL(prevObjectURL);
  prevObjectURL = objectURL;
}
Velimir Mlaker
  • 10,664
  • 4
  • 46
  • 58
-1

Save the images base64 in a temporary variable and replace the info with null.

Bwaxxlo
  • 1,860
  • 13
  • 18