使用新的Image()时javascript中的内存泄漏

时间:2011-09-25 10:30:37

标签: javascript memory-leaks image

我似乎有一个内存泄漏,因为在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;

1 个答案:

答案 0 :(得分:10)

首先关闭,因为您将图像存储在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;
}