• 软件:1711
  • 资讯:45336|
  • 收录网站:98302|

IT精英团

js系列之五:内存泄漏及解决方案

js系列之五:内存泄漏及解决方案

浏览次数:
评论次数:
编辑: 泽洋
信息来源: 51CTO博客
更新日期: 2021-07-22 12:19:32
摘要

js系列五:内存泄漏及解决方案,在IE下的JS编程中,以下的编程方式都会造成即使关闭IE也无法释放内存的问题,下面分类给出:varMyObject={};document.getElementById('myDiv').myProp=MyObject;解决方法:在window.onunload事件中写上:document.getElementById('myDiv').myProp=null;...

  • 资讯详情

在IE下的JS编程中,以下编程方式会造成即使关闭IE也无法释放内存的问题,分类如下:

var myObject={ };

document.getElementById('myDiv ')。myProp=MyObject

解决方法:

写入: document . getelementbyid(' my div ')。myprop=window . onunload事件中的null

2.DOM对象和JS对象相互引用。示例:

功能封装器(元件){ 0

this.elementReference=元素;

element.myProp=this

}

新封装器(document . getelementbyid(' myDiv '));

解决方法:

写入: document . getelementbyid(' my div ')。在onunload事件中,myprop=null

3.用attachEvent绑定DOM对象。示例:

函数doClick() {}

element.attachEvent('onclick ',doClick);

解决方法:

写入:元素。onunload事件中的separate vent(' onclick ',doclick );

4.从外到内执行appendChild。此时,即使调用了removeChild,也无法释放它。示例:

var ParentDiv=document . CreateElement(' div ');

var child div=document . create element(' div ');

document . body . appendchild(ParentDiv);

parentdiv . appendchild(childDiv);

解决方法:

由内向外执行附录:

var ParentDiv=document . CreateElement(' div ');

var child div=document . create element(' div ');

parentdiv . appendchild(childDiv);

document . body . appendchild(ParentDiv);

5.重复重写同一属性会造成大量内存占用(但IE关闭后会释放内存)。示例:

for(I=0;i 5000I){ 0

hostelement . text=' asdfasdfasdf ';

}

这个方法相当于定义了5000个属性!

解决方法:

其实:P是没有解决办法的~那就是编程的时候尽量避免这种情况

描述:

1.以上所有信息均来自微软MSDN官方网站,链接地址为:

http://msdn.microsoft.com/librar…e _ leak _ patterns . ASP

你可以在上面的地址看到详细的说明,包括例子和插图。只是我的英语不是很好,所以我读得不是很好。如果我犯了错误或者需要补充什么,请指出来。

2.对于第一篇文章,实际上包含了element.onclick=funcRef的编写,因为它也是对一个对象的引用。它应该在页面加载时释放。

3.至于第三项,在MSDN的英文描述中似乎是,即使调用了separavent,也无法释放内存,因为在attachEvent的时候已经造成了内存“LEAK”,但是使用了separavent之后情况会更好。我不知道是不是这样。请告诉我你是否擅长英语。

4.在实际编程中,这些内存问题的实际影响并不大,尤其是被客户使用时,客户永远不会注意到,但这些问题始终是程序员的心病——你是否总是对这样的bug感到不舒服?如果你能解决,你就能解决。这是最好的。事实上,在像webfx.eae.net这样的顶级JS源代码网站上,我可以看到上面的解决方案都是在其源代码中用于内存释放管理的。

了解并解决IEWeb开发的发展的内存泄漏模式

过去,Web开发人员不太注意内存泄漏。当时页面之间的链接大多比较简单,主要是在同一个中使用不同的连接地址

一个网站导航,这个设计非常有利于浏览器释放资源。即使在网页的操作中出现了资源泄漏,其影响也是非常有限的,而且经常发生

不会有人关心的。

今天人们对我们感兴趣

b应用有了高更的要求。一个页面很可能数小时不会发生URL跳转,并同时通过Web服务动态的更新页面内容。复杂的事件关联

设计、基于对象的JScript和DHTML技术的广泛采用,使得代码的能力达到了其承受的极限。在这样的情况和改变下,弄清楚内存泄露方式变得

非常的急迫,特别是过去这些问题都被传统的页面导航方法给屏蔽了。

还算好的事情是,当你明确了希望寻找什么时,内存泄露方式是比较容易被确定的。大多数你能遇到的泄露问题我们都已经知道,你只需

要少量额外的工作就会给你带来好处。虽然在一些页面中少量的小泄漏问题仍会发生,但是主要的问题还是很容易解决的。

泄露方式

在接下来的内容中,我们会讨论内存泄露方式,并为每种方式给出示例。其中一个重要的示例是JScript中的Closure技术,另一个示例是

在事件执行中使用Closures。当你熟悉本示例后,你就能找出并修改你已有的大多数内存泄漏问题,但是其它Closure相关的问题可能又会被忽

视。

现在让我们来看看这些个方式都有什么:
1、循环引用(Circular References) — IE浏览器的COM组件产生的对象实例和网页脚本引擎产生的对象实例相互引用,就会造成内存泄漏。

这也是Web页面中我们遇到的最常见和主要的泄漏方式;

2、内部函数引用(Closures) — Closures可以看成是目前引起大量问题的循环应用的一种特殊形式。由于依赖指定的关键字和语法结构,

Closures调用是比较容易被我们发现的;

3、页面交叉泄漏(Cross-Page Leaks) — 页面交叉泄漏其实是一种较小的泄漏,它通常在你浏览过程中,由于内部对象薄计引起。下面我们

会讨论DOM插入顺序的问题,在那个示例中你会发现只需要改动少量的代码,我们就可以避免对象薄计对对象构建带来的影响;

4、貌似泄漏(Pseudo-Leaks) — 这个不是真正的意义上的泄漏,不过如果你不了解它,你可能会在你的可用内存资源变得越来越少的时候极

度郁闷。为了演示这个问题,我们将通过重写Script元素中的内容来引发大量内存的"泄漏"。

循环引用

循环引用基本上是所有泄漏的始作俑者。通常情况下,脚本引擎通过垃圾收集器(GC)来处理循环引用,但是某些未知因数可能会妨碍从其

环境中释放资源。对于IE来说,某些DOM对象实例的状态是脚本无法得知的。下面是它们的基本原则:

Figure 1: 基本的循环引用模型

本模型中引起的泄漏问题基于COM的引用计数。脚本引擎对象会维持对DOM对象的引用,并在清理和释放DOM对象指针前等待所有引用的移除

。在我们的示例中,我们的脚本引擎对象上有两个引用:脚本引擎作用域和DOM对象的expando属性。当终止脚本引擎时第一个引用会释放,DOM

对象引用由于在等待脚本擎的释放而并不会被释放。你可能会认为检测并修复假设的这类问题会非常的容易,但事实上这样基本的的示例只是

冰山一角。你可能会在30个对象链的末尾发生循环引用,这样的问题排查起来将会是一场噩梦。

如果你仍不清楚这种泄漏方式在HTML代码里到底怎样,你可以通过一个全局脚本变量和一个DOM对象来引发并展现它。

// Next set up the element to script scope reference
document.getElementById(“LeakedDiv”).expandoProperty = myGlobalObject;
}

function BreakLeak()
{
document.getElementById(“LeakedDiv”).expandoProperty = null;
}

668 _ autosar _ rs _和templates通用文件
« 上一篇
返回列表
下一篇 »
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
你会是第一个来这里评论的人吗?
最近发布资讯
更多