javascript内存泄露

原文: http://www.pc6.com/infoview/Article_48896.html


以下是常见的几种javascript内存泄露的情况:

一、循环引用:

  1.  
  2.      
  3.          < script language ="JScript">
  4.          var  myGlobalObject;
  5.          function  SetupLeak()  // 产生循环引用,因此会造成内存泄露
  6.         {
  7.              //  First set up the script scope to element reference
  8.             myGlobalObject  = document.getElementById("LeakedDiv");
  9.              //  Next set up the element to script scope reference
  10.             document.getElementById("LeakedDiv").expandoProperty  =  myGlobalObject;
  11.         }
  12.          
  13.      
  14.      
  15.          
  16.      
  17.  

我们可以看到,myGlobalObject指向了一个DOM对象,而这个DOM对象的一个属性又指向了myGlobalObject,循环引用出现,内存泄露,其原理如下:

javascript内存泄露_第1张图片

解决方案很简单,在确保属性不再使用后,加入以下代码就可以了:

  1. function  BreakLeak ( ) {   // 解开循环引用,解决内存泄露问题
  2.           document. getElementById (  " LeakedDiv "  ). expandoProperty  =   null ;
  3. }

说起来容易,不过当我们程序非常复杂的时候,发现和修改就没有这么容易了.

二、闭包(Closures)

仍然先看一段代码:

  1.      
  2.          
  3.      
  4.          
  5.      

闭包的一个内部方法赋给了element对象,产生了一个作用域的循环引用,从而造成内存泄露.其原理图如下:

 javascript内存泄露_第2张图片

解决方案如下,在确定事件不再使用后,解除事件的绑定:

  1. function BreakLeak ( )  {
  2.      document. getElementById (”LeakedDiv” ). detachEvent (”onclick”, document. getElementById (”LeakedDiv” ). expandoClick );  
  3.      document. getElementById (”LeakedDiv” ). expandoClick =  null;
  4. }

通常情况下,常用的js框架都帮我们解决了这个问题,不需要我们自己处理,这也是使用框架的一个好处.

三、Cross-Page-Leaks

仍然先看一个例子:

  1.      
  2.          
  3.      
  4.      
  5.          
  6.          
  7.          
  8.      

LeakMemory和CleanMemory这两段函数的唯一区别就在于他们的代码的循序,从代码上看,两段代码的逻辑都没有错.

但LeakMemory却会造成泄露.原因是LeakMemory()会先建立起parentDiv和childDiv之间的连接,这时候,为了让 childDiv能够获知parentDiv的信息,因此IE需要先建立一个临时的scope对象.而后parentDiv建立了和 hostElement对象的联系,parentDiv和childDiv直接使用页面document的scope.可惜的是,IE不会释放刚才那个临时的scope对象的内存空间,直到我们跳转页面,这块空间才能被释放.而CleanMemory函数不同,他先把parentDiv和 hostElement建立联系,而后再把childDiv和parentDiv建立联系,这个过程不需要单独建立临时的scope,只要直接使用页面 document的scope就可以了, 所以也就不会造成内存泄露了.但是,需要特别说明一下,如果LeakMemory方法里面,创建的div对象上不绑定script事件,那么也不会有泄漏,这个可以理解为ie的bug,大家记住就可以了,不需要过分深究.其原理如下:

javascript内存泄露_第3张图片

四、Pseudo-Leaks:

同样可以理解为ie的bug的一种泄露:

  1.    
  2.        
  3.    
  4.  
  5.    
  6.        
  7.        
  8.    

没什么特别的好解释,记住就可以了.

关于这四种泄漏的具体描述,还是请各位参照原文:http://msdn.microsoft.com/en-us/library/Bb250448

以上是几种主要的泄露,当然,除此之外,网上还有一些其他的讨论,比如var str = "lalala";alert(str.length);这个简单的语句也会造成内存泄露,原因是类型转换的时候,ie生成了一个临时对象,这个临时对象被泄漏了.类似情况还有很多,大家有兴趣可以自己去搜集整理.

最后说一下,只要ie6还健在,作为前端开发人员,就不能逃避这些问题,当然,也不必过分深究,比如闭包的情况就比较难避免,就像我一开始说的,毕竟,javascript造成的内存泄露不是程序和项目的瓶颈,我们需要在各方面进行权衡.


你可能感兴趣的:(原生Js入门)