`
ywgoal
  • 浏览: 1893 次
  • 性别: 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 程序开发手册.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)浏览器上,这个问题尤为严重...

    JavaScript高级

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

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

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

    JavaScript飞机大战项目.rar

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

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

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

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

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

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

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

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

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

    JavaScript核心技术 PDF扫描版

    5.4嵌套函数、函数闭包和内存泄漏 5.5作为对象的函数 5.6习题 第6章捕捉事件 6.1O级DOM上的事件句柄 6.22级DOM上的事件句柄 6.3产生事件 6.4习题 第7章表单与即时验证 7.1访问表单 7.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应用,...

    Professional_JavaScript_for_Web_Developers.rar

    此外,JavaScript的错误处理和调试技巧也会有所涉及,帮助开发者解决程序中遇到的问题。 随着Web技术的发展,JavaScript在服务器端也扮演了重要角色。Node.js的出现使得JavaScript可以用于构建高性能的网络应用。书...

    javascript内存分配原理实例分析

    JavaScript是一种动态类型语言,它的内存管理机制对于理解代码性能至关重要。本文将深入探讨JavaScript的内存分配原理...在实际开发中,结合内存分析工具,我们可以进一步诊断和解决内存泄漏等问题,提升整体代码质量。

    文娱小程序电子书.zip

    此外,"避坑指南"部分将分享在小程序开发过程中可能遇到的问题及解决方案,可能包括兼容性问题、内存泄漏、网络请求处理、数据安全、用户体验优化等。这些经验教训对开发者来说极其宝贵,能帮助他们少走弯路,更快地...

    小程序源码 辅助类库 WebViewJS应用源码.rar

    在移动应用开发中,微信小程序和WebViewJS的结合使用是一个常见的技术实践,它允许开发者将网页内容嵌入到原生应用程序中,...通过学习这个源码,你可以了解实际开发中的最佳实践,并能解决在混合开发中遇到的问题。

    JavaScript程序的188个建议 高清PDF扫描版

    本书《JavaScript程序的188个建议》旨在帮助开发者,无论是初学者还是有经验者,提升他们的JS技能,理解并解决高级前端开发中可能遇到的问题。 1. **基础语法**:学习JavaScript首先要掌握基本语法,包括变量、数据...

    内存分析工具 MemoryAnalyzer-1.8.1-win32.x86-64.zip

    版本1.8.1-win32.x86_64是适用于Windows操作系统32位和64位环境的版本,它允许开发者和系统管理员深入理解应用程序的内存使用情况,从而找出可能导致性能问题或者内存泄漏的根源。 MemoryAnalyzer(MAT)是由...

    iOS中wkwebView内存泄漏与循环引用问题详解

    然而,使用WKWebView时,开发者可能会遇到内存泄漏和循环引用的问题,这些问题如果不妥善处理,可能会导致应用程序性能下降,甚至引发应用程序崩溃。 首先,我们需要理解内存泄漏的概念。内存泄漏是指程序中已分配...

Global site tag (gtag.js) - Google Analytics