使用 new Image() 时 JavaScript 中的内存泄漏
我似乎有内存泄漏,是由于在 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;
I seem to have a memory leak, caused by using the 'new Image()' in a javascript script. If I watch the used physical memory in the windows resource monitor, i get the expected increase in memory used when I load the page because it loads some quite large images using as follows:
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;
I would have though that when the page is navigated away from this would automatically destroy the references and free up the memory, but this doesn't seem to be the case. Instead, i navigate away and then go back to the page only the find the memory ramp up even more as it loads the images again without ever freeing up the previously allocated memory. I have tried manually removing references by putting code in the unload event to do this but it doesn't seem to make any difference. The variables were all initially declared with '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
});
does anyone have any pointers as to where I'm going wrong here? I thought the problem might be to do with circular references as i have built a list class where each item contains a reference to the previous and next image, but i have deeted these as follows:
delete galleries[i].pictures.Items[j].prev;
delete galleries[i].pictures.Items[j].next;
首先,据我所知,没有哪个浏览器会因为将图像存储在 JS 数组中而导致您转到另一个页面时发生泄漏。
如果您在 DOM <==> 之间存在循环引用,则某些较旧的浏览器会发生泄漏。 JS,其中一些 javascript 引用 DOM 元素,而 DOM 元素上的自定义属性又引用同一个 javacript 对象,但这似乎不是您这里所拥有的。
所以...如果您所看到的实际上是从一页到下一页的泄漏,我会感到惊讶。如果您确信确实如此,请创建一个可以与我们共享的普通网页,或者创建一个显示问题的 jsFiddle,并告诉我们您正在测试的具体浏览器以及您如何测量内存使用情况确定你有泄漏。
为了真正成为泄漏,每次您一遍又一遍地访问该页面时,您必须始终看到内存使用量不断上升。仅仅因为第二次访问该页面时总内存使用量稍高并不意味着存在泄漏。浏览器的一些数据结构会随着使用而增长(到一定程度),例如基于内存的缓存、会话浏览历史记录等……这些数据结构并不表示泄漏。
其次,我在您展示的数据结构中没有看到任何可以说明已知会导致旧版浏览器泄漏的循环引用类型的内容。
第三,
delete
运算符用于从对象中删除属性。这就是它的全部目的。请参阅以下文章:了解删除和MDN Delete 了解更多说明。因此,卸载处理程序中的清理代码没有正确使用delete
。您无法使用delete
删除变量或数组元素。虽然我不明白为什么这段代码是必要的,但如果你想要它,它会是这样的:First off, there is no browser that I know of that leaks when you go to another page just because you have images stored in a JS array.
There are some older browsers that leak if you have circular references between DOM <==> JS where some javascript refers to a DOM element and a custom attribute on the DOM element refers back to the same javacript object, but that does not appear to be what you have here.
So ... I'd be surprised if what you're seeing is actually a leak in going from one page to the next. If you're convinced it is, then create either a plain web page that you can share with us or a jsFiddle that shows the issue and tell us what exact browser you're testing in and exactly how you're measuring the memory usage that determines you have a leak.
For it to truly be a leak, you have to consistently see memory usage go up and and up and up, every time you go to the page over and over again. Just because total memory usage is a little bit higher the second time you go to the page does not mean you have a leak. The browser has some data structures that grow (to a point) with usage like the memory-based cache, the session browsing history, etc... that are not indicative of leaks.
Second off, I don't see anything in the data structures you've shown that are illustrative of the kinds of circular references that are known to cause leaks in older browsers.
Third off, the
delete
operator is for removing properties from an object. That's all it's for. See these articles: Understanding Delete and MDN Delete for a lot more explanation. So, your cleanup code in the unload handler is not usingdelete
properly. You cannot delete vars or array elements withdelete
. Though I can't see any reason why this code is necessary, if you were going to have it, it would be like this: