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,129
  • 4
  • 25
  • 36

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:

  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.
  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,151
  • 4
  • 43
  • 55
-1

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

Bwaxxlo
  • 1,860
  • 12
  • 18