Blob 对象与其数据之间的关系

Relationship between Blob object and its data

提问人:DisLido 提问时间:11/13/2023 最后编辑:DisLido 更新时间:11/13/2023 访问量:30

问:

当我用于获取其 url 时,blob 对象是否会被垃圾回收,并且随后不包含对该对象的任何引用?或者它不会在 url 被撤销之前被 GCed?createObjectURLBlob

async function getImageBlobURL() {
  const res = await fetch('/image.png');
  const blob = await res.blob(); // will it be GCed?
  const url = URL.createObjectURL(blob);
  return url;
}

const img = document.createElement('img');
const url = await getImageBlobURL();
img.url = url;
document.body.append(img);

我想做的是:

const finalizationRegistry = new FinalizationRegistry<string>((url) => {
  URL.revokeObjectURL(url);
});

/**
 * Get the URL of the blob, which will automatically revoke as the blob is GCed.
 * Anyone using this url must also hold the blob reference.
 */
export function getAutoRevokableBlobUrl(blob: Blob) {
  const url = URL.createObjectURL(blob);
  finalizationRegistry.register(blob, url);
  return url;
}

// how to use:
const img = document.createElement('img');
const url = getAutoRevokableBlobUrl(blob);
img.url = url;

// when the `img` removed and GCed, the `blob` can be GCed
// and the url will be automatically revoked in `finalizationRegistry`
img._blobObj = blob; 

document.body.append(img);
JavaScript DOM

评论

0赞 somethinghere 11/13/2023
我的猜测是不,它不会被收集,因为 URL 指向内存中的 blob。blob 只是内存中的一些字节,URL 不会对其进行编码,因为没有比内存块/blob 更好的编码 blob 的方法了。否则,效率将非常低下。
0赞 jsejcksn 11/13/2023
对于你的潜在问题:除非你使用的框架在删除元素时提供清理功能(例如 React 的渲染周期),否则使用 MutationObserver APIWeakMap 可能是从 DOM 中删除某些元素时撤销 blob URL 的惯用方法。
0赞 Bergi 11/13/2023
似乎您应该简单地将最终确定放在对象上,而不是放在imgblob

答:

2赞 Michael Liu 11/13/2023 #1

当我用于获取 Blob 对象的 URL 时,是否会对 Blob 对象进行垃圾回收,然后不保留对 Blob 对象的任何引用?createObjectURL

不,它不会。调用 时,从 URL 字符串到 Blob 的映射将添加到浏览器的内部“blob URL 存储”中。此映射使 Blob 保持活动状态,直到调用 .URL.createObjectURLURL.revokeObjectURL

因此,您的函数将不起作用。getAutoRevokableBlobUrl