介绍浏览器端的可靠性测试
在上一篇文章中我们介绍了浏览器端可靠性测试的概念、测试方法、以及常用的测试和分析工具。我们知道,浏览器端可靠性测试,就是以浏览器为测试平台,通过模拟用户在真实场景下的页面操作(点击、拖拽),来发现 Web 应用中潜在可靠性问题的测试。测试目的是确保 Web 应用在浏览器上能达到令人满意的用户体验和可靠性。
在浏览器的可靠性测试中,我们的测试重点,简单地说,就是浏览器进程的内存泄露。发现和分析这些内存泄露问题就是我们测试工作的主要目的。一般来说,我们可以通过手工测试、自动化测试的方法来发现浏览器进程的内存泄露。同时,借助一些分析工具,可以进一步帮助我们查看内存泄露的内容并分析原因,从而给开发人员提供有力的支持,使问题得到快速的解决。
浏览器端内存泄漏的原因
很多原因都可能导致浏览器端的内存泄露。按照与浏览器的相关性来分,有浏览器相关的内存泄露和浏览器不相关的内存泄露两种。
浏览器相关的内存泄露
所谓浏览器相关的内存泄露,是指在某种特定的浏览器下才会发生内存泄露,而在其他浏览器下并没有内存泄露。举个例子说,有些内存泄露问题只发生在 Internet Explorer 浏览器,而在 Firefox 上就没有泄漏。或者,一些内存泄露只发生在 Internet Explorer 浏览器 的某个版本上,比如在 6.0 的版本上,而在其他版本 Internet Explorer7.0 和 8.0 上就没有泄漏。
Internet Explorer 浏览器上的内存泄露
Internet Explorer 浏览器上的内存泄漏,是最常见的浏览器相关的内存泄漏问题。
微软 MSDN library 里有一篇讲述 Internet Explorer 浏览器的内存泄露模式的文章,非常详尽地讲解了 Internet Explorer 浏览器上的内存泄露的方式和原因,并加以举例。(http://msdn.microsoft.com/en-us/library/bb250448(VS.85).aspx)文章中将内存泄露的模式划分为四种:循环引用 (Circular References),闭包 (Closures),跨页面泄漏 (Cross-Page Leaks),伪泄漏 (Pseudo-Leaks)。
我们这里特别关注“循环引用”这种内存泄露模式。在 Internet Explorer 浏览器上, 我们遇到最多的内存泄露都是由于循环引用引起的。它的原理是这样的:JavaScript 是一种垃圾收集式语言,创建对象的时候分配给该对象内存,没有引用时收回内存。JavaScript 对象使用 Mark-and-Sweep 垃圾回收机制。然而,Internet Explorer 浏览器中的 COM(Component Object Model)对象使用的是 reference counting 的垃圾回收机制。所以,当两种使用不同垃圾回收机制的对象互相引用的时候,就会出现“循环引用”。一旦出现循环引用,引用计数器的值就只会增加,不会减少,所以就不能再达到零,对象无法满足垃圾回收的条件,也就不能回收引用对象使用的内存,就会造成内存泄露。
其他常见的内存泄露模式还有“闭包”。闭包功能非常强大,它们使内部函数在外部函数返回时也仍然可以保留对此外部函数变量的访问。但是,闭包非常易于隐藏 JavaScript 对象和 COM 对象间的循环引用,造成内存泄露问题。跨页面泄漏和伪泄漏遇到的不多,大家可以参看引用的文章自己进行学习。
好在,Internet Explorer 浏览器的内存泄露问题已经得到越来越多的关注。并且,随着 Internet Explorer 版本的不断更新,微软也在努力解决由浏览器本身的缺陷带来的内存泄露。比如,在推出 Internet Explorer 8.0 的时候,很多已知的内存泄露问题已经得到了解决或改善。从我们的实际测试中也看到,Internet Explorer 8 中的内存泄露问题明显少与 Internet Explorer 7。
尽管如此,仍然有许多用户在用着早先的 Internet Explorer 版本,对于测试人员来说,面对产品在不同 Internet Explorer 版本上的支持仍旧是一个挑战。
浏览器无关的内存泄露
浏览器不相关的内存泄露,就是指那些在几乎各种浏览器下都存在的内存泄露,这些泄露可能在程度上有所不同。比如说,某种页面操作会导致在 Internet Explorer 7.0 上 8M 的内存泄露, 而在 Firefox 3.0 浏览器上就只有 2M 的泄露。
代码逻辑的错误通常是导致这种内存泄露的主要原因。比如,在做某个操作的时候需要创建一些对象。在操作结束后应该及时销毁,再次操作的时候再重新创建。但由于代码逻辑的错误,可能会导致没有销毁或销毁动作失败,导致反复生成相同的对象,占用了过多的内存,造成内存泄露。