此代码导致浏览器内存泄漏是否正确?
/**
* @param {Canvas2DRenderingContext} ctx
* @param {string} url
*/
function loadImageDrawIntoCanvas(ctx, x, y, url) {
var img = new Image();
img.onload = function() {
ctx.drawImage(img, x, y);
}
img.src = url;
};
我的理解是,因为 img 是一个 DOM 元素,并且因为我使用 img.onload
将 JavaScript 附加到它,所以浏览器永远不会对其进行垃圾回收。要更正我需要清除 img.onload
中的
/**
* @param {Canvas2DRenderingContext} ctx
* @param {string} url
*/
function loadImageDrawIntoCanvas(ctx, x, y, url) {
var img = new Image();
img.onload = function() {
ctx.drawImage(img, x, y);
img.onload = null; // detach the javascript from the Image
img = null; // needed also so the closure doesn't keep
// a reference to the Image?
}
img.src = url;
};
最佳答案
只要浏览器正确实现,就不应该是泄漏。
旧版本的 Internet Explorer(7 及更早版本)的 GC 无法处理 JS 和 DOM 节点之间的循环引用。因此,有很多指南建议在删除 DOM 节点之前清除事件监听器,而 jQuery 会自动执行此操作。 (注意:其他浏览器可能在某些时候有错误的 GC,但旧的 IE 是著名的。)
这里有趣的部分是 GC 需要知道将来是否会再次触发 onload
。
我刚刚尝试使用类似于您发布的代码将 275 MB 的图像渲染到 Canvas 上,并且 Chrome 没有泄漏。 (相比之下,如果我将图像存储在循环外的数组中,则会保留 275 MB。)Firefox 可能会泄漏 [一些?],但很难说,因为它的内存开销比 Chrome 高得多。
为什么?
关于javascript - 在 img.onload 上留下处理程序是内存泄漏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37076977/