【问题标题】:JavaScript why window.URL.createObjectURL needs to be revoked?JavaScript 为什么 window.URL.createObjectURL 需要被撤销?
【发布时间】:2016-06-14 13:36:32
【问题描述】:
function f() {
   // some code.. then:
   var bloburl = URL.createObjectURL(canvasToBlobOutput)
   // I could would do the following line, but assume I don't
   // imgElement.src = bloburl;
   // will this leak memory?
 }

如果我取消注释 imgElement.src 行,我知道 img 元素会“挂钩”内存中的 blob 对象。但是,如果我们按原样运行函数(没有这一行),我看不出bloburl 不能被GCed 的原因?因为我们在函数之后没有引用它。

【问题讨论】:

  • MDN:URL.createObjectURL() 静态方法创建一个 DOMString,其中包含一个 URL,该 URL 表示参数中给定的对象。 URL 生命周期与创建它的窗口中的文档相关联。 浏览器将在卸载文档时自动释放它们;但是,为了获得最佳性能和内存使用,如果您可以在安全时间明确卸载它们,则应该这样做。
  • 请阅读,显然,当窗口/文档被卸载时,所有内容都会被释放。我只是不明白为什么即使没有引用该对象也会保留在内存中,据我所知,我的例子会泄漏内存

标签: javascript url garbage-collection window revokeobjecturl


【解决方案1】:

字符串不能作为 blob 的 GC 边缘,因为可以操作字符串。因此,必须将 blob 放入一个内部注册表中,以防止它被 GCed,以便可以从生成的 blob URI 加载它。

想象有一个隐藏的Map 实例和URL.createObjectURL 实现为:

function createObjectURL(blob) {
   let uri = generateRandomURI()
   window._hiddenMap.set(uri, blob)
   return uri
}

这样,当有人尝试加载该 URI 时,可以检查内部映射。但该映射还必须保持 blob 处于活动状态,因为 URI 可能是对该 blob 的唯一剩余引用。

要删除该 gc-edge,您必须撤销 URI。

【讨论】:

    猜你喜欢
    • 2021-07-29
    • 2021-03-03
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    相关资源
    最近更新 更多