javascript window.URL.revokeObjectURL() 不立即释放内存(或根本不释放)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7742825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 01:08:23  来源:igfitidea点击:

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

javascripthtmlfileapi

提问by Seb

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 FileReaderbut I have had some problems like in this post. so I change my way and I decided to use blob:url like ebidel recommands in the post, with window.URL.createObjectURL()and window.URL.revokeObjectURL()to release memory.

我正在制作一个 html 界面,通过拖放和多个选择文件在服务器上上传图像。我想在将图片发送到服务器之前显示图片。所以我首先尝试使用,FileReader但我在这篇文章中遇到了一些问题。所以我改变了我的方式,我决定使用 blob:url 就像帖子中的 ebidel 推荐一样,用window.URL.createObjectURL()window.URL.revokeObjectURL()来释放内存。

But now, I've got another problem, wich 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.

但是现在,我遇到了另一个问题,与这个问题类似。我希望客户可以一次上传 200 张图片,如果他愿意的话。但是浏览器崩溃了,使用的ram非常高!所以我想可能是同时显示了太多图像,我使用数组设置了一个带有等待文件队列的系统,以便一次只处理 10 个文件。但问题仍然存在。

On Google Chrome, if I check chrome://blob-internals/the files (which are normally already released by window.URL.revokeObjectURL()) are released approximatively 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)

在谷歌浏览器上,如果我检查chrome://blob-internals/文件(通常已经由window.URL.revokeObjectURL()发布)大约在 8 秒延迟后发布。在 Firefox 上我不确定,但似乎文件没有发布(我检查about:memory-> 图像)

Is my code which is bad, or is it a problem independent of me? Is there a solution to force the navigators to release immediatelly the memory? If it can help, this is the part of JavaScripton wich the problems occurs: (Sorry but I give here a link because of the image spam mechanism for new members) http://www26.zippyshare.com/v/14195278/file.html.

我的代码是坏的,还是一个独立于我的问题?有没有办法强制导航器立即释放内存?如果它可以提供帮助,这是出现问题的 JavaScripton 的一部分:(抱歉,由于新成员的图像垃圾邮件机制,我在这里提供了一个链接)http://www26.zippyshare.com/v/14195278/file。 html.

EDIT

编辑

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

这是一种自己的回答 + 对 bennlich 的回答(文本太长,无法发表评论)

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 revokeObjectURLmethod. Moreover, each browser manages the memory by its own way, leading to different behaviors. Here is how I came to this conclusion.

我从 user1835582 的回答中了解到,我确实可以删除 Blob/文件,但是当浏览器需要图像时,它会将它们保留在内存中的某个位置(这是合乎逻辑的)。因此,事实是显示图像(很多且很重)导致我崩溃和减速,而不是revokeObjectURL方法。此外,每个浏览器以自己的方式管理内存,导致不同的行为。这是我得出这个结论的方式。

First, let's try that revokeObjectURLworks 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)

首先,让我们尝试一下,revokeObjectURL使用https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Example.3A_Using_object_URLs_to_display_images的源代码的简单示例。使用 Chrome,您可以通过检查chrome://blob-internals/或尝试将显示的图像打开到一个空白的新选项卡来验证 Blob 是否已被很好地撤销。注意:要完全释放 Blob 引用,请添加document.getElementById("fileElem").value = "". 几年前我发布我的问题时,发布 blob 大约需要 8 秒,现在几乎是立即的(可能是由于 Chrome 和/或更好的计算机的改进)

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 revokeObjectURLmethod 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).

然后,是时候进行充电测试了。我用 100 张 jpg 约 2.5 Mo 做到了这一点。显示这些图像后,我滚动了页面。Chrome 崩溃,Firefox 运行缓慢(未在其他浏览器上测试)。然而,当我发表评论时,li.appendChild(img)一切都很顺利,即使有大量图像。这表明问题不是来自revokeObjectURL实际上正常工作的方法,而是来自显示大量沉重的图像。您还可以测试创建一个包含数百张重图像的简单 html 页面并滚动它 => 相同的结果(崩溃/减速)。

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.

最后,为了更深入地了解图像内存管理,在 Firefox 上查看 about:memory 很有趣。例如,我看到当窗口处于活动状态时,Firefox 会解压缩图像(图像 -> 未压缩堆上升),而原始(图像 -> 原始)总是稳定的(相对于加载的图像数量)。这里有一个关于内存管理的很好的讨论:http: //jeff.ecchi.ca/blog/2010/09/19/free-my-memory

采纳答案by user1835582

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

使用window.URL.revokeObjectURL()你只能得到[Blob][File]对象。您无法从内存中强制删除。

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.

笔记。浏览器尚未最终确定,它们可能会从这些设施中泄漏。如果您实施动画,则必须自行承担风险来理解这一点。

回答by logidelic

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:

这不是答案,但我只想说,据我所知,这仍然是最新版本的 Chrome (35) 中的一个问题。我做了一个暴露问题的测试页:

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

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).

如果您在计算机上选择大量(例如 600 张)高分辨率照片并将它们放入该页面的框中,Chrome 将崩溃(在 Windows 7 和 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
  1. 创建对象URL
  2. 加载 img(不要添加到 DOM!)
  3. revokeObjectURL 来释放引用
  4. 丢失 img 引用
  5. 对下一个放置的图像重复所有步骤

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

在任何给定时刻,似乎只有一个图像应该在内存中/被引用,但最终这会导致 Chrome 崩溃。