在Internet Explorer中,为什么即使离开页面,内存泄漏仍然存在?

6

《学习jQuery》一书中提到,IE存在内存泄漏问题,当DOM对象拥有一个引用函数的属性,并且该函数也引用了DOM对象,两者之间就会出现“循环引用”的情况,如下所示:

onload = function() {
    var foo = document.getElementById('foo');
    foo.onclick = function() {  // DOM object foo's onclick property refers to a function
       foo.innerHTML = "hello"  // the function's body refers to the DOM object
    }                           // therefore circular reference
}

IE可以处理循环引用的垃圾回收,但是当循环引用涉及DOM对象和Javascript对象时,则无法处理,因为它们由不同的内存管理器处理。
而且:
[内存泄漏...和]由此产生的[引用]循环即使在用户离开页面后IE也不能释放它,直到浏览器关闭。
这是真的吗?为什么IE即使用户离开页面也不释放这些内存?是因为用户可能会单击“返回”并返回页面,而IE希望保留页面的状态吗?在这种情况下,如果用户在内存泄漏页面上,然后单击“返回”,然后转到google.com怎么办?然后该页面将无法通过任何“返回”或“前进”查看,并且内存泄漏问题可以在不关闭浏览器的情况下消失吗?
甚至在关闭选项卡时,而不关闭浏览器时呢?
这种内存泄漏是否也会发生在IE 8中?

许多程序存在内存泄漏问题;虽然在较新的IE版本中已经修补了许多内存泄漏问题,但在这样一个规模的项目中要修补所有问题仍然很困难。 - Piskvor left the building
2个回答

4
内存泄漏是程序错误的一种,所以你基本上在问“为什么IE有bug?”答案显然是“因为某个程序员犯了一个错误”。
虽然一些浏览器在导航离开页面时故意保留页面状态(特别是Opera和FF),但“内存泄漏”意味着程序不再使用的内存,但却忘记释放。在这种情况下,IE已经停止关注内存的这部分,但没有告诉操作系统(Windows),后者仍将其视为“被IE使用”。因此,这部分内存处于无人区,直到关闭浏览器为止——因为当浏览器进程退出时,操作系统将标记分配给该进程的所有内存为“空闲”。
内存泄漏是一种相当隐匿的bug类型,因为程序似乎能够正确运行,但逐渐消耗更多的内存。
有关此主题的更多阅读,请参见例如http://en.wikipedia.org/wiki/Circular_referencehttp://en.wikipedia.org/wiki/Garbage_collection_(computer_science)

这些“循环引用”不是具有“页面级别”的范围吗?因此,当此页面泄漏内存并单击“返回”并转到google.com时,该页面基本上会从“返回”和“前进”序列中“消失”,我们可以释放与该页面相关的所有内存。 - nonopolarity
@Jian Lin: 是的,它应该是这样工作的。然而,IE的程序员可能忘记检查所有页面引用是否被正确释放了,因此尽管IE认为它已经正确清理了,但它在内存中留下了一些数据,并且不再知道它们的存在。 - Piskvor left the building
1
@Jian:如果那样能行就太好了。然而,这个问题仍然存在,这表明垃圾回收器认为内存仍然被正确引用(尽管可能是通过意外的路径),或者垃圾回收器太愚蠢以至于无法回收内存,甚至没有垃圾回收器。如果没有IE的源代码(或反编译它,这只是次优解),就无法评估问题所在。 - Donal Fellows
s/程序员/已经退休并在某处购买了一座岛屿的高薪架构师 - i_am_jorf
@jeffamaphone:这种错误通常是在比“系统架构”更低的层面引入的,我会说s/programmer/lowly code monkey/ ;) - Piskvor left the building
不,我认为在这种情况下不是这样的。JScript归DevDiv(即VS团队)所有,而MSHTML归IE团队所有。我相当确定问题出现在拥有两种不同架构上。 - i_am_jorf

1

内存泄漏的原因是应用程序(在这种情况下是IE)的其中一个程序员未能正确处理使用内存的某些东西(对象、资源)。

在MSDN上,托管应用程序中最常见的三个泄漏原因被认为是:

  • 持有托管对象的引用
  • 未能释放非托管资源
  • 未能处理绘图对象

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接