这段代码在浏览器中导致内存泄漏是否正确?
/**
* @param {Canvas2DRenderingContext} ctx
* @param {string} url
*/
function loadImageDrawIntoCanvas(ctx,x,y,url) {
var img = new Image();
img.onload = function() {
ctx.drawImage(img,y);
}
img.src = url;
};
我的理解是因为img是一个DOM元素,因为我用img.onload将JavaScript附加到它上面,浏览器永远不会垃圾收集它.要纠正我需要清除img.onload
/**
* @param {Canvas2DRenderingContext} ctx
* @param {string} url
*/
function loadImageDrawIntoCanvas(ctx,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和earler)有一个GC,无法处理JS和DOM节点之间的循环引用.有很多指南建议在删除DOM节点之前清除事件监听器,因为jQuery会自动执行此操作. (注意:其他浏览器可能在某些时候有过非常好的GC,但旧的IE是着名的.)
这里有趣的部分是GC需要知道onload是否会在将来再次被激活.
我刚尝试使用与您发布的代码类似的代码将275 MB的图像渲染到画布,Chrome不会泄漏. (相比之下,如果我将图像存储在循环外的数组中,则会保留275 MB.)Firefox可能会泄漏[某些?],但很难分辨,因为它的内存开销远远高于Chrome.
为什么?
>在javascript端,onload和loadImageDrawIntoCanvas都完成执行,并且没有剩余的对img的引用.
>在浏览器实现方面,当你调用img.src =时,它们在功能上等同于增加img上的引用计数,并在onload被触发时减少它. Chrome对这些类型的泄漏进行了两次测试(1,2).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。