我正在制作一个 html 界面,以通过拖放和多个选择文件在服务器上上传图像。我想在将图片发送到服务器之前显示它们。所以我第一次尝试使用FileReader
,但我遇到了一些问题,比如这篇文章。window.URL.createObjectURL()
所以我改变了我的方式,我决定像 ebidel 在帖子中推荐的那样使用 blob:urlwindow.URL.revokeObjectURL()
来释放内存。
但是现在,我遇到了另一个问题,与此类似。我希望客户可以根据需要一次上传 200 张图片。但是浏览器崩溃了,使用的内存非常高!所以我想可能是同时显示了太多图像,我使用数组设置了一个带有文件等待队列的系统,以便一次只处理 10 个文件。但问题仍然存在。
在谷歌浏览器上,如果我检查chrome://blob-internals/
文件(通常已经由window.URL.revokeObjectURL()
发布)大约在 8 秒延迟后发布。在 Firefox 上,我不确定,但似乎文件没有发布(我检查了about:memory
-> 图像)
我的代码是坏的,还是独立于我的问题?是否有强制导航器立即释放内存的解决方案?如果它可以提供帮助,这是发生问题的 JavaScript 部分:链接已过期,因为代码未包含在问题中。
编辑
这是一种自己的回答 + 对 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的源代码的简单示例。chrome://blob-internals/
使用 Chrome,您可以通过检查或尝试将显示的图像打开到一个空白的新选项卡来验证 Blob 是否已被很好地撤销。注意:要完全释放 Blob 引用,请添加document.getElementById("fileElem").value = ""
. 当我几年前发布我的问题时,释放 blob 大约需要 8 秒,现在几乎是立即的(可能是由于 Chrome 的改进和/或更好的计算机)
然后,是时候进行充电测试了。我用一百张大约 2.5 个月的 jpg 来做这件事。显示图像后,我滚动了页面。Chrome 崩溃并且 Firefox 很慢(未在其他浏览器上测试)。然而,当我评论li.appendChild(img)
一切顺利时,即使有一大堆图像。这表明问题不是来自revokeObjectURL
实际上工作正常的方法,而是来自显示大量重图像。您还可以测试创建一个包含数百张重图像的简单 html 页面并滚动它 => 相同的结果(崩溃/减速)。
最后,为了更深入地了解图像内存管理,在 Firefox 上查看 about:memory 很有趣。例如,我看到当窗口处于活动状态时,Firefox 解压缩图像(图像 -> 未压缩堆上升),而原始(图像 -> 原始)始终是稳定的(相对于加载的图像数量)。这里有一个关于内存管理的很好的讨论:http: //jeff.ecchi.ca/blog/2010/09/19/free-my-memory。