URL.revokeObjectURL无法移除Sources面板及chrome://blob-internals中的Blob
Blob未被垃圾回收的原因
- 闭包锁定Image实例:
setTimeout的回调作为闭包,会持续引用函数内的img变量,导致这个Image实例一直留在内存中,无法被JS引擎垃圾回收。 - Image实例持续持有Blob资源:即便调用了
URL.revokeObjectURL释放了object URL,只要Image对象还存在,它内部就会保留对对应Blob的引用,浏览器不会主动回收该Blob。
内存泄漏修复方案
核心是断开所有指向Blob的引用链,让JS引擎和浏览器可以正常回收资源。具体操作是在撤销URL后,主动清空Image的src并解除变量引用:
const compress = (file) => { const img = new Image(); img.src = URL.createObjectURL(file); console.log('url created'); setTimeout(() => { URL.revokeObjectURL(img.src); // 清空Image的src,切断对Blob的直接引用 img.src = ''; // 解除变量对Image实例的引用,让实例能被垃圾回收 img = null; console.log("url revoked"); }, 5000); };
如果需要更严谨的处理(比如确保Image加载完成后再执行清理),也可以监听Image的load或error事件,在回调中执行清理逻辑,避免不必要的资源持有:
const compress = (file) => { const img = new Image(); img.src = URL.createObjectURL(file); console.log('url created'); const cleanup = () => { URL.revokeObjectURL(img.src); img.src = ''; console.log("url revoked"); }; // 加载完成后延迟5秒清理 img.onload = () => setTimeout(cleanup, 5000); // 加载失败时直接清理 img.onerror = cleanup; };
内容的提问来源于stack exchange,提问作者roman465
相关产品推荐
相关产品推荐

