不附加 Image.onload 垃圾回收

4

如果通过var img=new Image()创建图像,并添加onload处理程序并设置img.src,那么尽管该图像未附加到DOM树中,仍会请求图像数据并调用onload。例如:

var img=new Image();
img.onload=function(){
    alert('Loaded!');
}
img.src='test.png';

这个图片什么时候被垃圾回收?JavaScript能否知道 onload 处理程序将被调用,且仅被调用一次,以便在此后释放图像?如果未设置 img.src,因此永远不会调用 onload,那么 JavaScript 是否会注意到并立即释放 img

1个回答

6
我使用测试页面进行了调查,以找到一个问题的答案 - 当JS创建带有事件处理程序的图像对象并未附加到DOM树时,它们何时被垃圾回收。
该页面中的JS代码通过document.createElement("img")new Image()也可以),创建1000个图像,附加2个事件处理程序(load和error),并设置src属性。
当所有图像都加载完成后,JS尝试显式地释放内存,在最后一个load事件中调用gc()(=同步),并立即将此图像的src设置为另一个URL。还设置了定时器,以便在稍后以异步方式进行第二次尝试释放内存。
Chrome开发者工具中的内存时间轴显示,第一次GC收集除最后一个外的所有图像。我解释为最后一个图像无法被GC,因为它正在加载新图片。 当第二次GC发生时,最后一个图像已经加载完成,并且也从内存中删除了。

Memory Timeline


这个实验的结论:

  • 即使在JS中没有链接到图像对象,load/error事件处理程序也会被调用,
  • 图像对象可以在图像加载过程完成后(成功或失败)被垃圾回收。

在Chrome Canary 33.0.1733.2中进行测试,使用--js-flags="--expose-gc"
源代码 http://pastebin.com/YZkGYmBC


这看起来是一种相当合理的行为。希望其他浏览器也能同样处理好这个问题。 - dronus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接