魔鬼的梦魇—验证IE中的js内存泄露模式(三)
按照Justin Rogers文章的顺序,接下来的这个模式应该是跨页内存泄露模式(cross-page leak),但是由于这个模式产生的中间对象,我们并不能访问到,所以我也想不到好的有可视效果的验证方式,所以就不介绍了,有兴趣的话大家可以看一下原文;今天简单的来学习这篇文章的最后一个模式Pesudo-Leak。
很多时候一些API运行的时候的实际行为和被期望的行为会导致你无法断定内存泄露的存在。Pseudo-leak几乎总是出现在进行动态脚本操作的同个页面内,并且当导航到一个空白页面后就很难察觉到泄露。我们需要做的就是怎样断定其不是跨页内存泄露,然后检测内存的消耗是否跟预期的相符。我们将会重写script文本标签作为验证这个模式的例子。
就像DOM的插入循序导致的问题一样,这个泄露模式也是由于创建的临时对象导致的泄露。通过一次又一次的重写一个script标签内部的文本,这样将会导致很多泄露的js对象被绑定到先前的内容中。
Justin Rogers在这个模式中给出的例子如下,我们同样也无法测试泄露的存在。
<html> <head> <script language="JScript"> function LeakMemory() { // Do it a lot, look at Task Manager for memory response for(i = 0; i < 5000; i++) { hostElement.text = "function foo() { }"; } } </script> </head> <body> <button οnclick="LeakMemory()">Memory Leaking Insert</button> <script id="hostElement">function foo() { }</script> </body> </html>
根据以上代码,我也写了一个测试例子,当第一次遍历覆盖script标签内容的时候,我们声明了一个数组,并将0压入数组,以后每次遍历都将相应的循环变量的值压入数组,最后我们输出数组的所有元素。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script id ="hostElement"></script> <script type="text/javascript"> var PseudoLeakTester = { leak: function () { this.makeLeak(); this.showLeakObject(); } , makeLeak: function () { for (var i = 0; i < 10; i++) { if (i == 0) { hostElement.text = "var testArray = new Array(); testArray.push(0)"; } else { hostElement.text = "testArray.push(" + i + ")"; } } } , showLeakObject: function () { alert(testArray.toString()); } }; PseudoLeakTester.leak(); </script> </head> <body> </body> </html>
运行的效果图如下。
图 1. 泄露验证例子运行输出结果