【问题标题】:Do I always need to call URL.revokeObjectURL() explicitly?我总是需要明确调用 URL.revokeObjectURL() 吗?
【发布时间】:2018-08-18 23:16:03
【问题描述】:

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

所以其中一种选择是不致电URL.revokeObjectURL();

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

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

【问题讨论】:

  • W3C File API - .revokeObjectURL: "虽然不限制 blob URL 的使用次数提供了更大的灵活性,但它增加了泄漏的可能性;开发人员应将其与对 URL.revokeObjectURL() 的相应调用配对。”

标签: javascript memory-leaks garbage-collection blob


【解决方案1】:

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

主要看你传递给createObjectURL的内容。

    1234563因此,在这种情况下,您可以创建大量此类,而无需将其撤消而没有真正的风险。 1234563及其数据,保护它免受 GC,直到文档死亡。在这种情况下,不要忘记在您不再需要它时撤销它。
  • 如果您传递来自用户设备的 MediaStream,不要,它已被弃用,原因很充分:至于生成的 Blob,UA 必须保持与外部设备在 blobURI 处于活动状态时打开,即使 MediaStream 已关闭,也可能会发生连接仍处于打开状态并导致无法请求新连接的情况。

【讨论】:

  • 感谢您提供更多信息,非常有用的详细信息有助于更好地理解。
  • “直到文档消亡”是什么意思
  • @DashiellRoseBark-Huss 直到页面被导航离开或关闭。
【解决方案2】:

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

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

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

¹这并不完全是它的实现方式,但它在推理可达性时相当好地描述了行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    相关资源
    最近更新 更多