我是否总是需要显式调用URL.revokeObjectURL()?

时间:2018-03-10 13:45:06

标签: javascript memory-leaks garbage-collection blob

我正在使用blob下载文件,问题是我想在下载文件后保留对象URL,而不对代码库进行重大更改。

因此,其中一个选项是不要拨打URL.revokeObjectURL();

依赖浏览器的垃圾收集器以避免任何内存泄漏是否安全?

我是否始终需要明确致电URL.revokeObjectURL();

2 个答案:

答案 0 :(得分:6)

另一个答案是对的,但我认为为了完整起见我应该添加一些信息。

这主要取决于您传递给createObjectURL的内容。

  • 如果您从<input type=file>传递用户选择的文件,那么您创建的blobURI是指向用户磁盘上文件的直接指针,此映射URI-file_path保存在记忆。因此,在这种情况下,你可以创建很多这些,而不必撤销它,没有真正的风险。

  • 如果你传递了你生成的Blob(或文件)(或者已经获取的),那么Blob必须存储在内存中,而blobURI确实会成为这个Blob的指针及其数据,保护它免受GC,直到文件死亡。在这种情况下,不要忘记在不再需要它时撤销它。

  • 如果您传递来自用户设备的MediaStream ,则不推荐使用它,原因很简单:至于生成的Blob,UAs必须保持与当blobURI处于活动状态时外部设备打开,即使MediaStream关闭,也可能发生连接仍然打开并导致无法请求新连接。

答案 1 :(得分:5)

  

依赖浏览器的垃圾收集器以避免任何内存泄漏是否安全?

createObjectURLabout¹所做的是创建创建的blob URL中的ID到与当前全局对象关联的隐藏Map中的实际blob的映射。这意味着从GC的角度看Blob remains reachable until either the global itself becomes collectible - 通常当您离开页面或关闭选项卡时 - 或者当映射被撤销时(假设这是最后一个引用)。

所以这取决于你认为的泄漏。它不会在浏览器的生命周期内保持活动状态,仅在当前页面的生命周期内保持活动状态。如果您希望其生命周期可能比当前页面短,则需要撤销。

¹这并不完全是如何实现的,但它在推理可达性时合理地描述了这种行为。