首  页 | 资讯中心 | 网络学院 | 天新汽车 | 天新手机 | 天新游戏 | 软件开发 | 考试认证
品 牌 机 | 笔 记 本 | 服 务 器 | 天新数码 - DC - DV - MP3 - MP4 - GPS - TV | 数字家庭
硬件 DIY - 主板 - CPU - 内 存 - 硬 盘 - 显示器 - 显卡 - 光驱 - 机箱 - 键鼠 - 网络设备
办公设备 | 打 印 机 | 扫 描 仪 | 投 影 仪 | 一 体 机 | 传 真 机 | 路 由 器 | 交 换 机
软件下载 | 驱动下载 | 游戏下载 | 源码下载 | 教程下载 | 站长在线 | 产品中心 | 报价中心
开发首页 | 开发语言 | .Net开发 | Java开发 | Web开发 | 数据库开发 | 移动开发 | 游戏开发 | 企业开发 | 操作系统 | 软件工程
VB VC Delphi PB BCB C++ - ASP.net C# VB.net - J2EE J2SE J2ME EJB - ASP PHP JSP CGI - MSSQL Oracle DB2 MySQL - CodingLife
  Web开发首页 | ASP开发 | PHP开发 | CGI开发 | Perl开发 | XML开发 | JavaScript | VBScript | Web服务器
  您现在的位置:天新网 > 软件开发 > Web开发 > JavaScript
Javascript教程:关于内存泄漏问题
http://dev.21tx.com 2008年04月14日 蓝色理想

每日文章精萃
.Net:.NET 2.0中的企业库异常处理块简述 Java:Eclipse插件开发之FindBugs插件
ASP:ASP讲座之一:网页开发利器:高效易 PHP:正则表达式系统教程(三)
JSP:Resin的使用和安装(1) CGI:用Perl语言进行Socket编程之四
VB:VB COM基础讲座之可重用性 VC:高质量C++编程点滴(一)

1 2 3 4 下一页

常规循环引用内存泄漏和Closure内存泄漏

要了解JavaScript的内存泄漏问题,首先要了解的就是javascript的GC原理。

我记得原来在犀牛书《JavaScript: The Definitive Guide》中看到过,IE使用的GC算法是计数器,因此只碰到循环 引用就会造成memory leakage。后来一直觉得和观察到的现象很不一致,直到看到Eric的文章,才明白犀牛书的说法没有说得很明确,估计该书成文后IE升级过算法吧。在IE 6中,对于javascript object内部,jscript使用的是mark-and-sweep算法,而对于javascript object与外部object(包括native object和VBscript object等等)的引用时,IE 6使用的才是计数器的算法。

Eric Lippert在http://blogs.msdn.com/ericlippert/archive/2003/09/17/53038.aspx一文中提到IE 6中JScript的GC算法使用的是nongeneration mark-and-sweep。对于javascript对算法的实现缺陷,文章如是说:

"The benefits of this approach are numerous, but the principle benefit is that circular references are not leaked unless the circular reference involves an object not owned by JScript. "

也就是说,IE 6对于纯粹的Script Objects间的Circular References是可以正确处理的,可惜它处理不了的是JScript与Native Object(例如Dom、ActiveX Object)之间的Circular References。

所以,当我们出现Native对象(例如Dom、ActiveX Object)与Javascript对象间的循环引用时,内存泄露的问题就出现了。当然,这个bug在IE 7中已经被修复了[http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html]。

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp 中有个示意图和简单的例子体现了这个问题:

<html>
<head>
<script language = " JScript ">
var myGlobalObject;
function  SetupLeak()  // 产生循环引用,因此会造成内存泄露
{
    //  First set up the script scope to element reference
    myGlobalObject  = document.getElementById("LeakedDiv");
    //  Next set up the element to script scope reference
    document.getElementById(" LeakedDiv ").expandoProperty  = myGlobalObject;
}
function  BreakLeak()  // 解开循环引用,解决内存泄露问题
{
    document.getElementById( " LeakedDiv " ).expandoProperty  = null ;
}
</script>
</head>
<body onload = "SetupLeak()"  onunload = "BreakLeak()">
<div id = "LeakedDiv" ></div>
</body>
</html>
   

上面这个例子,看似很简单就能够解决内存泄露的问题。可惜的是,当我们的代码中的结构复杂了以后,造成循环引用的原因开始变得多样,我们就没法那么容易观察到了,这时候,我们必须对代码进行仔细的检查。

尤其是当碰到Closure,当我们往Native对象(例如Dom对象、ActiveX Object)上绑定事件响应代码时,一个不小心,我们就会制造出Closure Memory Leak。其关键原因,其实和前者是一样的,也是一个跨javascript object和native object的循环引用。只是代码更为隐蔽,这个隐蔽性,是由于javascript的语言特性造成的。但在使用类似内嵌函数的时候,内嵌的函数有拥有一个reference指向外部函数的scope,包括外部函数的参数,因此也就很容易造成一个很隐蔽的循环引用,例如:

DOM_Node.onevent ->function_object.[ [ scope ] ] ->scope_chain ->Activation_object.nodeRef ->DOM_Node。

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp]有个例子极深刻地显示了该隐蔽性:

<html>
<head>
<script language = "JScript">
function  AttachEvents(element)
{
    //  This structure causes element to ref ClickEventHandler
    //  element有个引用指向函数ClickEventHandler()
    element.attachEvent("onclick", ClickEventHandler);
    function  ClickEventHandler(){
                 //  This closure refs element
                 //  该函数有个引用指向AttachEvents(element)调用Scope,也就是执行了参数element。
    }
}
function  SetupLeak()
{
    //  The leak happens all at once
    AttachEvents(document.getElementById("LeakedDiv"));
}
</script>
</head>
<body onload = "SetupLeak()"  onunload = "BreakLeak()">
<div id = "LeakedDiv"></div>
</body>
</html>

上一篇: Javascript教程:展示风格的价值
下一篇: Javascript事件处理代码的三种写法

1 2 3 4 下一页

编辑推荐
相关内容
·Javascript教程:实用的JS函数库
·JS和CSS实现的气泡窗口
·关于初次学习Ajax的一些心得
·Javascript+ASP打造无刷新新闻列表
·JSP+AJAX 添加、删除多选框
·如何使用Ajax技术开发Web应用程序(2)
·可编辑的 HTML JavaScript 表格控件 DataGr
·JavaScript[对象.属性]集锦之二
·javascript中如何实现浏览器上的右键菜单
·JavaScript[对象.属性]集锦之三
·Javascript教程:实用的JS函数库
·JavaScript教程:onmouseover控制图片
·JavaScript教程:用JS实现更复杂的交互范例
·JavaScript教程:如何访问框架?
·JavaScript教程:什么是框架?
·JavaScript教程:用JS脚本实现Web页面信息交
·JavaScript教程:JS窗体中的基本元素
·JavaScript教程:JavaScript窗体基础知识
·JavaScript教程:JS窗口及输入输出范例
·JavaScript教程:简单的输入、输出例子
最近更新
人气最热
·document.createElement()用法及注意事项
·学习JavaScript的事件
·PHP+JS实现搜索自动提示
·初学Ajax须注意的几个问题
·JavaScript扩展:正则像函数一样调用
·Javascript在IE和FF里的兼容问题
·Javascript教程:展示风格的价值
·Javascript事件处理代码的三种写法
·使用createElement动态创建HTML对象
·解决JS脚本兼容的几个小技巧
·国内外 Java Script 经典封装
·利用JavaScript创建功能强大的GUI
·javascript版的日期输入控件
·用Javascript轻松制作抽奖系统
·javaScript技巧(2):表单提交验证类
·用Javascript 实现的Dual listbox
·PHP+JS实现搜索自动提示
·奇妙的Javascript图片放大镜
·一个非常强大完整的web表单验证程序
·JavaScript图形库

 
·[硬件]音箱品牌大全 - 罗技
·[数码]16GB容量将登场 iAUDIO主流MP3全看
·[汽车]长丰猎豹经销商暗自降价 3款车降幅2000
·[开发]PO部分常用table 总结 PO01A(采购单)sq
·[资讯]去年国内制造业ERP普及率仅10.4%
·[游戏]《天堂2》银月的闪耀
·[本本]全面开花是表象 移动市场AMD仍需努力
·[办公]小型商务首选 日立商用投影8500元抱走
·[手机]新人必读 整理篇多普达310软件安装方法
·[考试]孙涛:英语不及格的优秀保研生
·[学院]3DS MAX装个矢量渲染插件Illustrate
·[娱乐]包饺子
 

关于我们 | 联系我们 | 广告服务 | 工作机会 | 版权声明 | 欢迎投稿 | 网站地图
Copyright © 2000-2008 , www.21tx.com , All Rights Reserved .
© 晨新科技 版权所有 Created by TXSite.net