2
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 的原因?因为我们在函数之后没有引用它。

4

1 回答 1

3

字符串不能作为 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。

于 2016-06-14T21:37:36.857 回答