window.URL.revokeObjectURL() 不会立即释放内存(或根本不释放)?
我正在制作一个 html 界面,用于使用 Drag & 将图像上传到服务器上。拖放和多选文件。我想在将图片发送到服务器之前显示它们。所以我首先尝试使用 FileReader
但我遇到了一些问题,例如 这篇文章。所以我改变了我的方式,我决定使用 blob:url 就像 ebidel 在帖子中推荐的那样,使用 window.URL.createObjectURL()
和 window.URL.revokeObjectURL()
来释放内存。
但现在,我遇到了另一个问题,类似于 这个。我希望客户如果愿意的话可以一次上传 200 张图片。但是浏览器崩溃了,并且使用的内存非常高!所以我认为可能同时显示的图像太多了,我使用数组设置了一个带有文件等待队列的系统,以便一次只处理 10 个文件。但问题仍然出现。
在 Google Chrome 上,如果我检查 chrome://blob-internals/ 文件(通常已经由 window.URL.revokeObjectURL()
发布)大约会在8秒延迟。在 Firefox 上,我不确定,但看起来文件是否没有发布(我检查 about:memory
-> 图像)
是我的代码不好,还是有问题独立于我?有没有办法强制导航器立即释放内存?如果它可以提供帮助,这是 JavaScript 中出现问题的部分:链接已过期,因为问题中未包含代码。
编辑
这是一种自己的答案+对bennlich的答案(评论文本太长)
我从user1835582的答案中了解到我确实可以删除Blob/文件,但当浏览器需要图像时,它将它们保存在内存中的某个位置(这是合乎逻辑的)。因此,显示图像(很多且很重)的事实给我带来了崩溃和崩溃。速度变慢,而不是 revokeObjectURL
方法。此外,每个浏览器都以自己的方式管理内存,从而导致不同的行为。我是这样得出这个结论的。
首先,让我们尝试一下 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 和/或更好的计算机的改进)
然后,是时候进行充电测试了。我用了一百张 jpg,每张大约 2.5 Mo。显示图像后,我滚动页面。 Chrome 崩溃了,Firefox 运行缓慢(未在其他浏览器上测试过)。然而,当我评论 li.appendChild(img)
时,一切都很顺利,即使有大量图像。这表明问题并非来自实际上正常工作的 revokeObjectURL
方法,而是来自显示大量繁重的图像。您还可以测试创建一个包含数百个繁重图像的简单 html 页面并滚动它 =>相同的结果(崩溃/减慢)。
最后,为了更深入地了解图像内存管理,在 Firefox 上查看 about:memory 很有趣。例如,我看到当窗口处于活动状态时,Firefox 会解压缩图像(图像 -> 未压缩堆上升),而原始数据(图像 -> 原始数据)始终稳定(相对于加载的图像数量)。这里有关于内存管理的很好的讨论:http:// jeff.ecchi.ca/blog/2010/09/19/free-my-memory。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用window.URL.revokeObjectURL(),您只能获取[Blob]或[File]对象。您不能强制从内存中删除。
注意。
浏览器尚未最终确定,它们可能会从这些设施中泄漏。如果您实现动画,则必须自行承担风险来理解它。
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.
这不是一个答案,但我只是想说,据我所知,这仍然是最新版本 Chrome (35) 中的一个问题。我制作了一个暴露问题的测试页面:
http://ecobyte.com/tmp/chromecrash-1a .html
如果您在计算机上选择大量(例如 600 张)高分辨率照片并将它们放入该页面上的框中,则会导致 Chrome 崩溃(在 Windows 7 和 Mac OS X 上尝试过) 10.8.5)。
如果您查看源代码,您可以看到操作顺序是:
看起来只有一个图像应该在任何给定时刻都在内存中/被引用,但最终这会导致 Chrome 崩溃。
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:
Seems like only a single image should be in memory/referenced at any given moment, but eventually this crashes Chrome.