第二种:将一个DOM对象和一个JS对象相互成为对方的属性。对于这点,IE官方也都有说法:在IE6中,对于 javascript object内部,jscript使用的是mark-and-sweep算法,而对于javascript object与外部object(包括native object和vbscript object等等)的引用时,IE 6使用的才是计数器的算法。也是说,IE 6对于纯粹的Script Objects间的Circular References是可以正确处理的,可惜它处理不了的是JScript与Native Object(例如Dom、ActiveX Object)之间的Circular References。所以,当我们出现Native对象(例如Dom、ActiveX Object)与Javascript对象间的循环引用时,内存泄露的问题出现了。当然,这个bug在IE 7中已经被修复了。(Fuck,难怪我用Drip测试不出来(系统是IE8的内核))。下面是我的一个测试:

 

function Encapsulator(element){
this.elementReference = element;
element.expandoProperty = this;
}
function SetupLeak2(){
var obj=new Encapsulator(document.getElementById("test"));
document.body.removeChild(document.getElementById("test"));
//alert(document.getElementById("test").expandoProperty); 出现错误
//说明从element.expandoProperty ---> obj的引用已经断开了
//但是从obj.elementReference到element的引用依然存在,
//这样的话在IE6下element无法回收内存,但是其他浏览器的GC机制都会很好的处理了这个问题。
document.body.appendChild(obj.elementReference);
}

  第三种:将事件处理函数放在定义它的函数的内部。这种情况之前看到过,回想下自己以前编写js的方式:外包一个自执行函数,里面定义闭包内的变量和功能函数,也不乏对事件处理程序的处理。这样是否会造成IE下的内存泄漏呢?下面是两个测试程序:

 

var test=function(){
var div=document.getElementById("test");
var i=0;
while((i++) < 20){
(function(index){
var o=document.createElement("p");
o.innerHTML="AAA";
o.onclick=function(){
alert("haha,leap");
}
div.appendChild(o);
o.onclick=null;
div.removeChild(o);
})(i);
}
}
function addEvent(){
var div=document.getElementById("event");
div.onclick=function(){
this.parentNode.removeChild(this);
}
}

  上面的一段程序也是从网上摘录下来做测试的,在闭包中动态生成一个div元素,并给它添加事件,事件处理程序写在闭包里面,也是内涵在test函数里 面,可是在removeChild的时候,Drip下显示还是内存泄漏了,即使是把它的onclick属性设置为null也不行。第二个测试程序中,在事 件处理程序中通过removeChild删除当前节点的时候,也显示内存泄漏。
  第四种:在创建DOM对象时插入script。这个还是第一次看到。即是通过createElement创建DOM元 素的时候,直接在字符串中插入了js代码:document.createElement(“<div onclick=’foo();’>”),但是这种方式只在IE下有效。通过测试下面的程序,在Drip中也确实显示内存泄漏了
  var leakMemory=function(){
  for(i = 0; i < 5000; i++){
  var parentDiv = document.createElement("<div onClick='foo()'>");
  }
  }
  第五种:总是先将新创建的DOM对象插入到文档后,在对其进行其他操作。对于这点,我想象不到它是如何造成内存泄漏 的。而且,它跟页面优化的一些方式可能存在冲突。在某些情况下,在创建了DOM元素之后,先处理DOM的操作,后才插入到文档中,这样可以避免尽可能的 由于reflow影响性能的情况。这可能需要一个权衡了吧,因地制宜~
  总结:
  上面是本人通过使用Drip工具测试的结果,但是由于在sIEVE和JS Leaps Detector下测试都没发现内存泄漏的情况,所以纠结的很。经过这一番折腾,也不枉自己一番倒腾倒腾吧,在以后的编写代码中,可以或多或少的去避免这 些不必要的可能造成内存泄漏的情况出现。
  同时,如果有说错的地方,欢迎指正,共同学习~~