非附加的Image.onload垃圾收集

时间:2013-04-01 01:33:09

标签: javascript event-handling garbage-collection

如果通过var img=new Image()创建了图片,则会添加onload处理程序并设置img.src,将请求图像数据,并且尽管图像已调用onload没有附加到DOM树。例如

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

此图像何时以及如何被垃圾收集? JavaScript是否能够知道onload处理程序将被调用,并且只调用一次,以便之后释放图像?如果未设置img.src,则会注意到JavaScript,因此永远不会调用onload并且可以立即释放img吗?

1 个答案:

答案 0 :(得分:5)

我使用test page进行了一些调查,以找到问题的答案 - 当使用事件处理程序(在JS中创建但未附加到DOM树)的图像对象被垃圾收集时。

页面中的JS代码通过document.createElement("img")创建1000个图像(new Image()以相同的方式工作),附加2个事件处理程序(加载和错误)并设置src属性。 /> 加载所有图像后,JS会尝试释放内存,在上次加载事件中显式调用gc()(=同步)并立即将此图像的src设置为另一个URL。此外,计时器设置为第二次尝试释放内存,因此以后以异步方式完成。

Chrome开发者工具中的内存时间线显示第一个GC收集除最后一个之外的所有图像。我将此解释为最后一张图像无法进行GC,因为它正在加载新图片。 当第二个GC发生时,最后一个图像已经加载,它也会从内存中删除。

Memory Timeline


我从这个实验得出的结论:

  • 调用load / error事件处理程序,如果没有指向图像的链接,则调用event 对象存在于JS,
  • 当图像加载过程完成(成功或失败)时,可以对图像对象进行垃圾回收。

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