【问题标题】:Memory leak in javascript when using new Image()使用 new Image() 时 javascript 中的内存泄漏
【发布时间】:2011-09-25 23:34:45
【问题描述】:

我似乎有内存泄漏,这是由于在 javascript 脚本中使用“new Image()”引起的。如果我在 Windows 资源监视器中查看使用的物理内存,我会在加载页面时得到预期的内存使用增加,因为它使用如下方式加载了一些相当大的图像:

var imgObjs = [];

// in for loop i = 0, 1, 2...
imgObjs[i] = new Image();
imgObjs[i].onload = function(event) {
    // image loaded
}
imgObjs[this.img_src].src = this.img_src;

我会认为当页面导航离开时会自动破坏引用并释放内存,但情况似乎并非如此。取而代之的是,我离开然后返回页面,发现内存增加得更多,因为它再次加载图像而没有释放先前分配的内存。我尝试通过将代码放入 unload 事件中来手动删除引用,但它似乎没有任何区别。这些变量最初都是用'var'声明的:

// allow garbage collection by removing references
$(window).unload(function() {
    for(var i in imgObjs) {
    imgObjs[i] = null;
    delete imgObjs[i];
}
delete imgObjs

// delete other variables that reference the images
});

有没有人知道我在哪里出错了?我认为问题可能与循环引用有关,因为我已经构建了一个列表类,其中每个项目都包含对上一张和下一张图像的引用,但我将这些内容如下:

delete galleries[i].pictures.Items[j].prev;
delete galleries[i].pictures.Items[j].next;

【问题讨论】:

标签: javascript memory-leaks image


【解决方案1】:

首先,据我所知,没有浏览器会因为您将图像存储在 JS 数组中而在转到另一个页面时发生泄漏。

如果您在 DOM JS 之间有循环引用,一些较旧的浏览器会泄漏,其中一些 javascript 引用 DOM 元素并且 DOM 元素上的自定义属性引用回同一个 javacript 对象,但这不会看起来就是你这里的东西。

所以...如果您看到的实际上是从一页到下一页的泄漏,我会感到惊讶。如果您确信它是,然后创建一个可以与我们共享的普通网页或一个显示问题的 jsFiddle,并告诉我们您正在测试的确切浏览器以及您如何测量内存使用情况确定您有泄漏。

要让它真正成为泄漏,您必须始终看到内存使用量不断增加,并且每次您一遍又一遍地访问该页面。仅仅因为第二次访问该页面时总内存使用量略高并不意味着您有泄漏。浏览器有一些数据结构会随着使用而增长(达到一定程度),例如基于内存的缓存、会话浏览历史记录等……这些数据结构并不表示泄漏。

第二,我在您展示的数据结构中看不到任何说明已知会导致旧浏览器泄漏的循环引用类型的任何内容。

第三关闭,delete 运算符用于从对象中删除属性。这就是它的全部目的。请参阅这些文章:Understanding DeleteMDN Delete 以获得更多解释。因此,卸载处理程序中的清理代码没有正确使用delete。您不能使用delete 删除变量或数组元素。虽然我看不出有什么理由需要这段代码,但如果你要拥有它,它会是这样的:

// allow garbage collection by removing references
$(window).unload(function() {
    for (var i = 0; i < imgObjs.length; i++) {
        imgObjs[i] = null;
    }
    imgObjs = null;
}

【讨论】:

  • 感谢您的反馈。我制作了一个自定义的“CircularListItem”类,旨在代表我正在制作的图像轮播。我没有发布代码,因为我不知道它有多相关,或者我是否误解了更基本的东西。我想我要做的就是查看您提供的文章,看看我是否可以更深入地理解并更新它,如果我弄清楚发生了什么。
  • 自从发布此内容后,我发现按照您的建议将它们设置为 null 而不是明显滥用“删除”似乎可以让浏览器释放内存。在此之前,每次刷新页面时内存都会以明显的步骤增加,直到我拥有的 4GB 内存中的大部分都已满!感谢您的建议。
  • 完全同意!我觉得这个答案必须包含在每一本 JS 书里!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 2016-01-06
相关资源
最近更新 更多