关于Javascript的内存泄漏问题(2)
作者:海啸 来源:海啸博客 发布时间:2008-04-15 07:46:00
标签:内存,泄露,javascript
还有这个例子在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>
0
投稿
猜你喜欢
- 1.首先,我们需要过滤所有客户端提交的内容,其中包括?id=N一类,另外还有提交的html代码中的操作数据库的select及asp文件操作语
- 安装MySQL假设你把所有必须的源码或者包都放在了/tmp下。如果你下载的是RPM包的话,那比较简单;如果你下载的是二进制包(你没有rpm程
- 一看,C盘只有不到2M可用空间,一查原因,sqlserver安装路径下的log目录文件占了好大,5G多, 于是上网搜了下,解决了: 把与sq
- 前段时间做一个小项目碰到了一个导航制作的方式然后突然想到曾经很久以前看到的梯形状的不规则导航,就尝试做了一下。结果碰到了几个问题,后来在同事
- 如果您还没看过段正淳的css笔记(1)分类之间的横竖线,可以先看看!1、css圆角的做法.为了这个圆角,前段开发们付出的努力是在是太多了.又
- 用XMlhttp生成html页面,相关函数如下:<% ’定义xmlhttp function Get
- clipboardData 对象提供了对于预定义的剪贴板格式的访问,以便在编辑操作中使用。成员表方法 描述 clearData 通过 dat
- 在用户登录windows操作系统的时候,如果触发到了登录表单的密码录入框上,并且此时按下了“大写锁定键(Caps Lock)”,那么界面上会
- MySQL使用环境变量TMPDIR的值作为保存临时文件的目录的路径名。如果未设置TMPDIR,MySQL将使用系统的默认值,通常为/tmp、
- 抽象工厂模式Abstract Factory Pattern是什么抽象工厂模式是一种创建型模式,它提供了一种创建一系列相关或相互依赖对象的最
- 由于可将 Microsoft? SQL Server? 2000 设置为包含一个或多个命名实例和一个默认实例(也可无),所以要用新命名规则来
- 几个月来好像就现在暂时无需求,稍微轻松一下,然后在Q群中发现有人提问,怎么用CSS实现数学公式“四又二分之一”。对于这个公式个人
- monfs :我想知道javascript是否可以实现这样的功能来改变本地的IP地址,例如我本地设置的IP地址是192.168.0.1,我想
- 下面的request.servervariables例子都是服务器探针采用的asp代码本机ip:<%=request.serverva
- 代码如下:< % '功能:显示数据库中表名、字段名、字段内容 '原创:wangsdong
- jQuery中文入门指南,翻译加实例,jQuery的起点教程中文版译者:Keel此文以实例为基础一步步说明了jQuery的工作方式。现以中文
- 昨天晚上睡觉前突然想到的,在此记一笔。传统方式以前我们做文章系统或新闻发布系统的时候,做文章内链(标签)的时候,通常是通过以下方式来实现的:
- 1、从外部文档中粘贴时,如果不想要其格式,只要文字,可以使用“Edit->paste as text”命令,而不要直接Ctrl+V。2
- SQL Server管理,你做得好吗?下文这些可能会对你的工作有一些帮助,不妨耐心的看看吧。1. 数据库文件有.mdf .ndf .ldf三
- ps:不曾想还有那么好用的方法。汗一个先。Div即父容器不根据内容自适应高度,我们看下面的代码:<div id="main&