关于Javascript的内存泄漏问题(2)

作者:海啸 来源:海啸博客 时间:2008-04-15 07:46:00 

还有这个例子在IE 6中同样原因会引起泄露

function  leakmaybe() {
var  elm  =  document.createElement("DIV");
     elm.onclick  =  function(){
         return   2   +   2 ;
     }
}
for( var  i = 0 ;i < 10000;i ++){
  leakmaybe();
}

关于Closure的知识,大家可以看看 这篇文章 ,习惯中文也可以看看zkjbeyond的blog,他对Closure 这篇文章进行了 简要的翻译 。之所以会有这一系列的问题,关键就在于javascript是种函数式脚本解析语言,因此javascript中“函数中的变量的作用域是定义作用域,而不是动态作用域”,这点在犀牛书《JavaScript: The Definitive Guide》中的“Funtion”一章中有所讨论。

http://support.microsoft.com/default.aspx?scid=KB;EN-US;830555中也对这个问题举了很详细的例子。

一些简单的解决方案

目前大多数ajax前端的javascript framework都利用对事件的管理,解决了该问题。

如果你需要自己解决这个问题,可以参考以下的一些方法:

http://outofhanwell.com/ieleak/index.php?title=Main_Page:有个不错的检测工具

http://youngpup.net/2005/0221010713 中提到:可以利用递归Dom树,解除event绑定,从而解除循环引用:

if (window.attachEvent){         
    var clearElementProps = ['data','onmouseover','onmouseout','onmousedown','onmouseup',
'ondblclick','onclick','onselectstart','oncontextmenu'];         
   
    window.attachEvent("onunload", function(){            
        var el;
        for(var d = document.all.length;d--;){                 
            el = document.all[d];                 
                for(var c = clearElementProps.length;c--;){                     
                    el[clearElementProps[c]] = null;                 
                }             
            }         
        }
    );     
}

http://novemberborn.net/javascript/event-cache一文中则通过增加EventCache,从而给出一个相对结构化的解决方案

/*    
    EventCache Version 1.0
    Copyright 2005 Mark Wubben
    Provides a way for automagically removing events from nodes and thus preventing memory leakage.
    See <http://novemberborn.net/javascript/event-cache> for more information.
   
    This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
*/
/* 
    Implement array.push for browsers which don't support it natively.
    Please remove this if it's already in other code 
*/
if (Array.prototype.push == null ){
    Array.prototype.push =  function (){
         for (var i = 0;i<arguments.length;i ++){
             this[this.length] = arguments[i];
         };
         return this.length;
    };
};
/*    
    Event Cache uses an anonymous function to create a hidden scope chain.
    This is to prevent scoping issues. 
*/
var EventCache = function (){
     var listEvents=[];
     return{
        listEvents : listEvents,
   
        add: function(node, sEventName, fHandler, bCapture){
            listEvents.push(arguments);
        },
   
        flush: function (){
             var i,item;
             for (i = listEvents.length-1;i>=0;i=i-1 ){
                item=listEvents[i];
                if(item[0].removeEventListener){
                    item[0].removeEventListener(item[1],item[2],item[3]);
                };
               
                /* From this point on we need the event names to be prefixed with 'on"  */
                if(item[1].substring(0, 2)!="on" ){
                    item[1]="on"+item[1];
                };
               
                if(item[0].detachEvent){
                    item[0].detachEvent(item[1], item[2]);
                };
               
                item[0][item[1]]=null;
            };
        }
    };
}();

使用方法也很简单:

<script type="text/javascript">
function addEvent(oEventTarget,sEventType,fDest){       
if(oEventTarget.attachEvent){       
     oEventTarget.attachEvent("on" + sEventType, fDest);   
}
elseif(oEventTarget.addEventListener){       
     oEventTarget.addEventListener(sEventType, fDest, true);    
}
elseif(typeof oEventTarget[sEventType]=="function"){               
     var fOld = oEventTarget[sEventType];       
     oEventTarget[sEventType] = function(e){
         fOld(e);
         fDest(e);
     };   
}
else {       
     oEventTarget[sEventType] = fDest;   
};
   
/* Implementing EventCache for all event systems */   
EventCache.add(oEventTarget, sEventType, fDest, true);};
function createLeak(){        
     var body = document.body;   
     function someHandler(){              
         return body;   
     };   
         addEvent(body, "click", someHandler);
};
    
window.onload = function(){      
     var i = 500;      
     while(i > 0){       
          createLeak();       
          i = i - 1;
     }
};
    
window.onunload = EventCache.flush;
</script>

标签:内存,泄露,javascript
0
投稿

猜你喜欢

  • python视频转化字节问题的完整实现

    2023-05-21 16:55:28
  • python和c语言哪个更适合初学者

    2022-06-22 08:23:29
  • python3 lambda表达式详解

    2021-03-01 20:28:20
  • Python字符串的全排列算法实例详解

    2023-04-30 17:01:05
  • python怎么判断模块安装完成

    2022-11-25 12:58:56
  • cordova+vue+webapp使用html5获取地理位置的方法

    2024-04-27 16:00:05
  • mysql 获取表有多少列

    2010-10-14 13:44:00
  • python之django路由和视图案例教程

    2021-06-24 09:48:09
  • ASP实例:处理多关键词查询实例代码

    2008-11-24 12:56:00
  • python文件编译为pyc后运行的实现步骤

    2021-03-08 22:36:46
  • Python大批量搜索引擎图像爬虫工具详解

    2021-09-15 15:30:02
  • python中字符串变二维数组的实例讲解

    2021-08-03 04:37:56
  • 六行python代码的爱心曲线详解

    2022-04-09 23:15:17
  • Python从入门到实战之数据结构篇

    2023-10-16 21:32:30
  • textarea 在IE和FF下换行无法正常显示的解决方法

    2022-09-11 01:33:40
  • avalon js实现仿google plus图片多张拖动排序附源码下载

    2024-04-30 09:52:27
  • python超详细实现字体反爬流程

    2022-08-30 22:39:03
  • python中的列表和元组实例详解

    2023-07-26 23:04:12
  • 基于python中的TCP及UDP(详解)

    2023-12-22 19:54:38
  • Python 如何反方向迭代一个序列

    2022-12-07 09:44:19
  • asp之家 网络编程 m.aspxhome.com