`
ywgoal
  • 浏览: 1914 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

程序开发中遇到的Javascript 内存泄漏问题

阅读更多
内存泄漏,就是内存不能够被正确地配置,内存不能及时有效回收,他会导致程序执行效率降低甚至执行失败。

在浏览器领域,大部分都可能会出现内存泄漏问题,但是以IE最为多见,也最为严重,尤其是页面中有许多Javascript的交互效果的时候。其中涉及到循环结构(cyclic structure)、DOM对象属性、JavaScript对象属性以及垃圾回收器(garbage collector)。

循环结构(cyclic structure),是指一个DOM对象包含JavaScript对象参数(事件处理函数),JavaScript对象又包含了DOM对象的属性参数。(比如给某个超链接A添加一个onclick事件函数,这时候A就有了相应的事件处理函数,而JavaScript函数对象中也有了A的onclick属性)。

当循环结构(cyclic structure)形成时如果没有别的参数传递给DOM对象或者Javascript函数对象,JavaScript的垃圾回收器(一个自动内存管理器)就会把这两个对象的内存释放并重新进行配置,但是IE的DOM对象属性参数并不能由JavaScript管理清除(不能清除DOM对象的属性参数),而他自己的内存管理机制并不能理解循环结构(cyclic structure)的垃圾回收机制。因此,当循环结构(cyclic structure)的垃圾回收条件形成时,IE也不能进行正确的内存回收管理,导致内存泄漏。当然,这只有在循环结构的未回收内存的数量达到很大的数量级的时候,才会出现明显的内存泄漏症状。



最近做一个公司的业务系统,公司要求能尽可能的与c/s近似,也就是如c/s一样,点击文本框可以弹出此项目的相关内容,进行选择输入。

     我使用了弹出窗口,然后在子窗口双击选中项目,把选中的值返回给父窗体。

     在系统做完了之后,在客户使用的过程,由于客户使用的是512m的内存配置,所以在打开了30--40个窗体之后,ie的虚拟内存占用量达到近200m,从而使系统变慢,javascript的运行也变慢了。



      在google搜了一下之后,才知道可能是由于ie的内存泄漏引起的。具体可以参看www.cnblogs.com中的相关文章。



      我使用任务管理器,打开一个弹出窗口,ie内存就增加1-3m,然后关闭窗口,有时内存并不释放,有时才释放几十k。看来问题出在了内存释放上面。



      接着按内存释放这个思路,进行搜索查找方法,来进行解决这个问题。我找到一个javascript未公开的函数CollectGarbage,这个函数是用来进行内存释放的。我在所有的弹出窗口结束之前把所有的自己定义的javasctip的变量设置为null,并调用CollectGarbage函数。



      javascript中把变量设为null,javascript并不会把内存释放,当下次再次定义变量时,就会覆盖此变量所在的内存。如果不设为null,javascript再次定义变量时,会开辟一个新的内存空间。



      在使用以上处理之后,再次打开窗口,ie的内存每次还是增加1-3m,但是在关闭窗口之后,则ie会释放一定数量的内存在500k至2m。起到了一定的作用。

       由于我在页面中使用了第三方的控件,第三方的控件中的javascript中的内存是如何管理,就不是由我来控制的了。

    

1.javascript内存释放的方法示例



  把所有上级函数的参数即使设为null,并使用CollectGarbage来释放内存。 



示例

  <script> 

  

  //32M 

  function   AllocMem() 

  { 

  var   str="12345678"; 

  for(var   i=3;i<24;i++) 

  str+=str; 

  return   str; 

  } 

  

  function   A(a) 

  { 

  a=null; 

  return   r; 

  function   r() 

  { 

  } 

  } 

  var   f=A(AllocMem()); 

  alert(1); 

  CollectGarbage(); 

  //明显,已经释放了。 

  r=null; 

  alert(2); 

  CollectGarbage(); 

  

  </script> 

  

  里面对于内存释放的规则(脚本层)已经理解得很透了。 

  (每一层菜单分配?M的内存.对着任务管理器才看到情况) 



注:

CollectGarbage()通常会在核心推出内存,因就是IE或NS程序结束的时候才会调用.这样才是安全的 



说明:

1)   如果你在另一个window中keep了该window中的object的reference,即使关闭该window,内存也没有释放 

  

  As   you   might   know,   windows   opened   with   window.open()   may   share   a   process   with   its   opener   (_blank   or   _new     window   may   not).   That   is,   even   if   you   see   those   two   windows   on   the   desktop,   if   you   look   at   the   process   table   in   the   Task   Manager,   you   may   only   see   one   IEXPLORE.EXE   running.   Memory   may   only   be   released   when   the   process   is   terminated 

   

2)更糟糕的是,如果你keep的是一个DOM   object的reference,   关闭该object   所在window,   IE会crash,   报内存错误(或者要求,重新启动) 

  

  I   would   say   this   looks   like   a   bug,   you   might   want   to   report   to   Microsoft

http://www.cnblogs.com/chillsrc/archive/2006/12/28/606544.html

IE下产生内存泄漏的几种情况以及解决办法 - [javascript开发]

1、给DOM对象添加的属性是一个对象的引用。
范例:   
var MyObject = {};   
document.getElementById('myDiv').myProp = MyObject;   
解决方法:   
在window.onunload事件中写上: document.getElementById('myDiv').myProp = null;     
2、DOM对象与JS对象相互引用。
范例:   
function Encapsulator(element) {   
  this.elementReference = element;   
  element.myProp = this;   
}   
new  Encapsulator(document.getElementById('myDiv'));   
解决方法:   
在onunload事件中写上: document.getElementById('myDiv').myProp = null;   
   
3、给DOM对象用attachEvent绑定事件。
范例:   
function doClick() {}   
element.attachEvent("onclick", doClick);   
解决方法:   
在onunload事件中写上: element.detachEvent('onclick', doClick);   
   
4、从外到内执行appendChild。这时即使调用removeChild也无法释放。
范例:   
var parentDiv =  document.createElement("div");   
var childDiv = document.createElement("div");   
document.body.appendChild(parentDiv);   
parentDiv.appendChild(childDiv);   
解决方法:   
从内到外执行appendChild:   
var parentDiv =  document.createElement("div");   
var childDiv = document.createElement("div");   
parentDiv.appendChild(childDiv);   
document.body.appendChild(parentDiv);   
 
 
5、反复重写同一个属性会造成内存大量占用(但关闭IE后内存会被释放)。
范例:   
for(i = 0; i < 5000; i++) {   
  hostElement.text = "asdfasdfasdf";   
}   
这种方式相当于定义了5000个属性!   
解决方法:   
其实没什么解决方法:P~~~就是编程的时候尽量避免出现这种情况咯~~   
   
说明:   
1、以上资料均来源于微软官方的MSDN站点,链接地址:   
http://msdn.microsoft.com/librar ... e_leak_patterns.asp   
大家可以到上面这个地址中看到详细的说明,包括范例和图例都有。只是我英文不太好,看不太懂,如果我上述有失误或有需要补充的地方请大家指出。   
  2、对于第一条,事实上包括 element.onclick = funcRef 这种写法也算在其中,因为这也是一个对对象的引用。在页面onunload时应该释放掉。   
3、对于第三条,在MSDN的英文说明中好像是说即使调用detachEvent也无法释放内存,因为在attachEvent的时候就已经造成内存“LEAK”了,不过detachEvent后情况还是会好一点。不知道是不是这样,请英文好的亲能够指出。   
  4、在实际编程中,这些内存问题的实际影响并不大,尤其是给客户使用时,客户对此绝不会有察觉,然而这些问题对于程序员来说却始终是个心病 --- 有这样的BUG心里总会觉得不舒服吧?能解决则给与解决,这样是最好的。
分享到:
评论

相关推荐

    常见的JavaScript内存泄露原因及解决方案.docx

    ### 常见的JavaScript内存泄露原因及解决方案 #### 引言 在现代Web开发中,JavaScript已成为构建复杂用户界面的主要编程语言之一。随着应用程序变得越来越庞大与复杂,有效地管理和优化内存成为确保应用性能和用户...

    JavaScript 程序开发手册.rar_javascript_javascript manual_javascript 手册

    通过《JavaScript程序开发手册》,开发者可以系统地学习JavaScript的各个方面,提升编程技能,解决实际开发中遇到的问题。"www.pudn.com.txt"可能是手册中的某个部分或者示例代码,而"JavaScript 程序开发手册"则是...

    extjs 2.2 内存泄漏补丁

    在2.2版本中,尽管它提供了许多优秀的功能,但与许多其他JavaScript库一样,ExtJS 2.2也存在一些已知的问题,其中最令人关注的是内存泄漏问题。尤其是在老旧的Internet Explorer 6(IE6)浏览器上,这个问题尤为严重...

    01-JS内存泄漏.md

    JS内存泄漏是前端开发过程中经常遇到的问题,它指的是程序中已分配的内存由于某些原因未被释放或者无法释放,导致应用程序可用的内存逐渐减少。本节将详细探讨JS内存泄漏的原因、检测方法以及如何预防和解决内存泄漏...

    防止动态加载JavaScript引起的内存泄漏问题

    内存泄漏是指程序中已经分配的内存由于疏忽或者其他原因而未能释放,导致这些内存区域无法再被后续使用,且持续占用系统资源直到程序结束。在Web浏览器中,如果一段JavaScript代码不再需要,浏览器理应能够清理这...

    JS常见内存泄漏及解决方案解析

    标题“JS常见内存泄漏及解决方案解析”主要讲述了JavaScript中内存泄漏的类型和各种解决方案,以便读者能够在实际开发中避免此类问题,提高程序的性能和稳定性。内存泄漏是指程序中分配的内存由于错误或疏忽未被适当...

    JavaScript高级

    8. **性能优化**:包括DOM操作的优化、减少全局变量的使用、使用事件委托、避免内存泄漏等,这些都是提升JavaScript代码性能的关键。 9. **模块化**:CommonJS、AMD、ES6模块,以及Webpack、Rollup等工具,帮助我们...

    收集记录一些使用Javascript,JQuery时遇到的问题

    博客中可能还包括了一些具体的例子、代码片段和解决方法,如使用`console.log()`进行调试、如何避免内存泄漏、以及如何有效地组合使用JavaScript和jQuery等。通过阅读和实践,你可以加深对这两种语言的理解,更好地...

    JavaScript核心技术 PDF扫描版

    5.4嵌套函数、函数闭包和内存泄漏 5.5作为对象的函数 5.6习题 第6章捕捉事件 6.1O级DOM上的事件句柄 6.22级DOM上的事件句柄 6.3产生事件 6.4习题 第7章表单与即时验证 7.1访问表单 7.2把事件附加在表单上:不同的...

    更快开发ASP.NET程序的25个秘密

    32. 使用Chrome开发者工具诊断JavaScript内存泄漏:当开发者遇到应用程序中的内存泄漏问题时,可以使用Chrome开发者工具来诊断和修复问题。 33. 监控内存消耗:持续监控应用程序的内存消耗,可以帮助开发者及时发现...

    JavaScript飞机大战项目.rar

    《JavaScript飞机大战项目详解》 JavaScript,作为一门广泛应用于网页和网络应用开发的脚本语言,是前端开发的重要基石。...在实践中,你会遇到各种问题并找到解决办法,这样的过程将极大地丰富你的编程经验和技巧。

    cordova扫码插件phonegap-plugin-barcodescanner,修复了在ios10上面的内存泄漏导致的闪退bug

    内存泄漏是编程中的常见问题,当程序无法释放不再使用的内存时,会导致系统资源耗尽,影响应用的稳定性和性能。在iOS环境中,由于其严格的内存管理机制,这个问题尤为突出。 修复这个bug的关键在于识别并消除导致...

    java和JavaScript开发细节

    ### Java与JavaScript开发要点详解 ...综上所述,无论是Java还是JavaScript的开发,都需要开发者具备良好的编程习惯和严谨的思维逻辑,才能有效地避免常见的错误和潜在的性能问题,从而构建出高质量的应用程序。

    查找并修复JavaScript代码中的问题.zip

    在JavaScript编程过程中,遇到错误和问题是在所难免的。这个名为"查找并修复JavaScript代码中的问题.zip"的压缩包显然提供了关于如何诊断和解决这些常见问题的资源。它包含两个文件:一个说明文本(说明.txt)和一个...

    基于JavaScript的富客户端表格绘制库开发.pdf

    摘要:本文介绍了一种基于JavaScript的富客户端表格绘制库的开发,旨在解决运维和开发工作中遇到的难题。该库实现了单元格事件绑定、翻页、单元格嵌入复杂模块、锁定表头表列、动态表列配置、浏览器端导入导出文本...

    DOC-JS-Leaked-Memory:一些关于javascript泄漏内存调试的免费文档

    二、JavaScript内存泄漏类型 1. 长期存在的全局变量:全局变量在整个脚本生命周期内都存在,若未正确清理,可能导致内存占用不减。 2. 闭包:闭包可以访问并保持对外部作用域的引用,即使外部函数已经执行完毕,...

    ExtJS内存调试工具 sIEve

    针对ExtJS应用在Internet Explorer浏览器中的内存泄漏问题,出现了专门的内存调试工具——sIEve。 sIEve是一款专门用于检测和分析ExtJS应用在IE浏览器中内存泄漏的工具。由于早期的Internet Explorer浏览器在内存...

    cpp-mJS用于CC的嵌入式JavaScript引擎

    这意味着你需要了解如何创建和释放JavaScript对象,以及如何处理可能出现的内存泄漏问题。 3. **安全**:在嵌入式环境中,安全性至关重要。`cpp-mJS` 提供了一定程度的安全控制,但作为开发者,你需要确保在执行...

    动态显示JSP服务器内存的Ajax程序.Rar

    4. `说明.html`:这是项目中的一个文档,可能包含了关于如何使用此程序、其工作原理以及可能遇到的问题的详细说明。 总的来说,这个程序结合了Ajax、JSP和CSS等技术,创建了一个能够实时监控服务器内存的Web应用,...

Global site tag (gtag.js) - Google Analytics