Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

window.URL.revokeObjectURL() doesn't release memory immediately (or not at all)?

I'm making an html interface to upload images on a server with Drag & Drop and multiple selection files. I want to display the pictures before sending them to the server. So I first try to use FileReader but I have had some problems like in this post. so I change my way and I decided to use blob:url like ebidel recommends in the post, with window.URL.createObjectURL() and window.URL.revokeObjectURL() to release memory.

But now, I've got another problem, which is similar to this one. I want that a client could upload 200 images at time if he wants. But the browser crashed and the ram used was very high! So I thought that maybe too much images were displayed at the same time, and I set up a system with a waiting queue of files using an array, in order to treat only 10 files at time. But the problem still occurs.

On Google Chrome, if I check chrome://blob-internals/ the files (which are normally already released by window.URL.revokeObjectURL()) are released approximately after a 8 seconds delay. On Firefox I'm not sure but it seems like if the files were not released (I check on about:memory -> images for that)

Is my code which is bad, or is it a problem independent of me? Is there a solution to force the navigators to release immediately the memory? If it can help, this is the part of JavaScripton which the problems occurs: link expired because code was not included in question.

EDIT

This is a kind of own answer + an answer to bennlich (too long text for a comment)

I understood from the answer of user1835582 that I could indeed remove the Blob/File but while the browser needs images it keeps them somewhere in memory (which is logical). So it's the fact to display images (many & heavy) that gave me crashes & slow downs, not the revokeObjectURL method. Moreover, each browser manages the memory by its own way, leading to different behaviors. Here is how I came to this conclusion.

First, let's try that revokeObjectURL works well, with a simple example using the source code of https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Example.3A_Using_object_URLs_to_display_images. Using Chrome you can verify that Blob are well revoked, by checking chrome://blob-internals/ or trying to open displayed images into a new tab that will be blank. Note : to fully release Blob references, add document.getElementById("fileElem").value = "". When I posted my question some years ago, it was about 8 seconds to release blob, now it's almost immediate (probably due to improvements in Chrome & / or to a better computer)

Then, time for a charge test. I did it with a hundred of jpg of ~2.5 Mo each. After that images have been displayed, I scrolled the page. Chrome crashed and Firefox was slow (not tested on others browsers). However, when I commented li.appendChild(img) all went well, even with a huge bunch of images. This shows that problems are not coming from revokeObjectURL method which in fact works properly, but from displaying lot of heavy images. You can also test to create a simple html page with hundreds of heavy images and scroll it => same result (crash / slow down).

Finally to look deeper about images memory management, it's interesting on Firefox to look into about:memory. For example I saw that when the window is active, Firefox uncompresses the images (images -> uncompressed-heap goes up), while raw (images -> raw) is always stable (relative to the the quantity of images loaded). There is a good discussion about memory management here : http://jeff.ecchi.ca/blog/2010/09/19/free-my-memory.

like image 992
Seb Avatar asked Oct 12 '11 15:10

Seb


People also ask

What does URL createObjectURL do?

The URL. createObjectURL() static method creates a string containing a URL representing the object given in the parameter. The URL lifetime is tied to the document in the window on which it was created. The new object URL represents the specified File object or Blob object.

What is revokeObjectURL?

revokeObjectURL() The URL. revokeObjectURL() static method releases an existing object URL which was previously created by calling URL. createObjectURL() . Call this method when you've finished using an object URL to let the browser know not to keep the reference to the file any longer.


2 Answers

With window.URL.revokeObjectURL() you can only get [Blob] or [File] object. You can not force remove from memory.

Note. Browsers are not finalized and they can leak from these facilities. If you implement the animation, you have to understand that at your own risk.

like image 191
user1835582 Avatar answered Sep 19 '22 08:09

user1835582


This isn't an answer, but I just want to say that, as far as I can tell, this is still an issue in the latest version of Chrome (35). I made a test page that exposes the problem:

http://ecobyte.com/tmp/chromecrash-1a.html

If you select a large number (say, 600) of high resolution photos on your computer and drop them into the box on that page, it will crash Chrome (tried on Windows 7 and Mac OS X 10.8.5).

If you look at the source you can see that sequence of ops is:

  1. createObjectURL
  2. load the img (don't add to DOM!)
  3. revokeObjectURL to free the ref
  4. Lose the img ref
  5. Repeat all steps for next dropped image

Seems like only a single image should be in memory/referenced at any given moment, but eventually this crashes Chrome.

like image 36
logidelic Avatar answered Sep 19 '22 08:09

logidelic