我正在制作一个 html 界面,通过拖放和多个选择文件将图像上传到服务器上。我想在将图片发送到服务器之前显示它们。所以我首先尝试使用FileReader
但我遇到了一些问题,比如这个帖子 https://stackoverflow.com/questions/6217652/html5-file-api-crashes-chrome-when-using-readasdataurl-to-load-a-selected-image/6298889#6298889。所以我改变了我的方式,我决定使用 blob:url 就像 ebidel 在帖子中推荐的那样,window.URL.createObjectURL()
and window.URL.revokeObjectURL()
来释放内存。
但现在,我遇到了另一个问题,类似于this one https://stackoverflow.com/questions/7167180/understanding-object-urls-for-client-side-files-and-how-to-free-the-memory。我希望客户如果愿意的话可以一次上传 200 张图片。但是浏览器崩溃了,并且使用的内存非常高!所以我认为可能同时显示的图像太多了,我使用数组设置了一个带有文件等待队列的系统,以便一次只处理 10 个文件。但问题仍然出现。
在 Google Chrome 上,如果我检查chrome://blob-internals/
文件(通常已经由window.URL.revokeObjectURL()
)大约在 8 秒延迟后释放。在 Firefox 上我不确定,但似乎这些文件没有发布(我检查了about:memory
-> 图像)
是我的代码不好,还是它是一个独立于我的问题?有没有办法强制导航器立即释放内存?如果它可以帮助的话,这是 JavaScript 中出现问题的部分:链接已过期,因为问题中未包含代码.
EDIT
这是一种自己的答案+对 bennlich 的答案(评论文本太长)
我从 user1835582 的回答中了解到,我确实可以删除 Blob/File,但是当浏览器需要图像时,它将它们保留在内存中的某个位置(这是合乎逻辑的)。因此,事实上是显示图像(很多且很重)导致我崩溃和速度变慢,而不是revokeObjectURL
方法。此外,每个浏览器都以自己的方式管理内存,从而导致不同的行为。我是这样得出这个结论的。
首先,让我们尝试一下revokeObjectURL
效果很好,有一个使用源代码的简单示例https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Example.3A_Using_object_URLs_to_display_images https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Example.3A_Using_object_URLs_to_display_images。
使用 Chrome,您可以通过检查来验证 Blob 是否已被撤销chrome://blob-internals/
或者尝试将显示的图像打开到一个空白的新选项卡中。注意:要完全释放 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 http://jeff.ecchi.ca/blog/2010/09/19/free-my-memory.