使用new Image()时javascript内存泄漏

Memory leak in javascript when using new Image()

本文关键字:javascript 内存 泄漏 new Image 使用      更新时间:2023-09-26

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

我本来以为,当页面被导航离开这将自动销毁引用和释放内存,但这似乎不是情况。相反,我导航离开,然后回到页面,只是发现内存增加更多,因为它再次加载图像,而没有释放以前分配的内存。我已经尝试通过在卸载事件中放置代码来手动删除引用,但它似乎没有任何区别。这些变量最初都是用'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;

首先关闭,没有浏览器,我知道,当你去另一个页面只是因为你有图像存储在一个JS数组泄漏。

有一些旧的浏览器泄漏,如果你有DOM <==> JS之间的循环引用,其中一些javascript引用一个DOM元素和DOM元素上的自定义属性引用回相同的javascript对象,但这似乎不是你在这里。

所以…如果您看到的实际上是从一页到下一页的泄漏,我会感到惊讶。如果你确信是这样,那么创建一个普通的网页,你可以与我们分享,或者创建一个jsFiddle,显示这个问题,并告诉我们你正在测试的确切浏览器,以及你是如何测量内存使用来确定你有泄漏的。

对于真正的泄漏,您必须始终如一地看到内存使用不断增加,每次您一次又一次地访问该页面。仅仅因为第二次访问该页面时总内存使用量稍微高一些,并不意味着存在泄漏。浏览器有一些数据结构会随着使用而增长(到一定程度),比如基于内存的缓存、会话浏览历史等等。这些都不是泄漏的迹象。

第二个关闭,我在你所展示的数据结构中没有看到任何说明循环引用类型的东西,这些引用在旧浏览器中已知会导致泄漏。

第三个关闭,delete操作符用于从对象中删除属性。这就是它的全部意义。请参阅这两篇文章:了解删除和MDN删除以获得更多解释。因此,卸载处理程序中的清理代码没有正确使用delete。不能使用delete删除变量或数组元素。虽然我看不出为什么这段代码是必要的,但如果你想要它,它应该是这样的:

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