JavaScript中如何正确释放Blob及createObjectURL占用的内存?
解决createObjectURL引发的内存泄漏问题
这个问题我之前也碰到过,核心原因是你忽略了URL.createObjectURL()的关键特性:它生成的URL会持续持有对Blob的内存引用,除非你主动调用URL.revokeObjectURL()释放,哪怕你关闭了对话框,浏览器也不会自动回收这部分内存,最终导致泄漏。
首先先补全你没写完的dataURItoBlob函数(标准的base64转Blob实现):
function dataURItoBlob(dataURI) { // 拆分data URI的元信息和数据部分 const [metaStr, dataStr] = dataURI.split(','); // 提取MIME类型 const mimeMatch = metaStr.match(/:(.*?);/); const mime = mimeMatch ? mimeMatch[1] : 'application/octet-stream'; // 解码base64字符串为二进制数据 const binaryString = atob(dataStr); const byteArray = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { byteArray[i] = binaryString.charCodeAt(i); } return new Blob([byteArray], { type: mime }); }
接下来是修正后的SweetAlert2调用代码,关键是在对话框关闭的所有可能路径中调用revokeObjectURL:
import swal from 'sweetalert2'; function showImageDialog(dataURI) { const blob = dataURItoBlob(dataURI); // 创建Object URL const objectURL = URL.createObjectURL(blob); swal.fire({ title: '图片预览', imageUrl: objectURL, imageAlt: '预览图片', showCloseButton: true, // 可根据需求添加其他配置,比如禁止点击外部关闭等 }) // 对话框关闭(无论用户点击确认、关闭、ESC还是外部区域)都会触发此回调 .then(() => { URL.revokeObjectURL(objectURL); }) // 异常场景下也要确保撤销URL,避免内存泄漏 .catch(() => { URL.revokeObjectURL(objectURL); }); }
额外注意事项
- 不要重复使用同一个
objectURL:每次生成新的Blob都要创建新的URL,用完就立即撤销。 - 如果同时展示多个Blob,建议维护一个
Set或数组存储所有生成的objectURL,在清理时批量调用revokeObjectURL。 - 测试时可以用Chrome DevTools的Memory面板拍快照对比:调用函数前拍一次,关闭对话框后再拍一次,确认Blob对象已被回收。
内容的提问来源于stack exchange,提问作者twoLeftFeet
相关产品推荐
相关产品推荐

