`
dengwanchuan
  • 浏览: 46783 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

IE内存泄露之JQuery html(),append()

阅读更多

最近俺在测试一个Java Web项目时,遇到了一个问题。这个问题对这个项目产生了很大的影响(主要

是项目web的布局框架),所以写下来让大家一起帮帮忙寻找解决之法!

 

这个问题是在使用Jquery.html()时发现IE的内存成几何的增长,永久没有回落,最后造成IE内存溢出。

 

以下是根据公司项目内容模拟的场景代码:

 

 

[html] view plaincopy
 
  1. <span style="font-size:18px;"><html>  
  2. <head>  
  3.     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  4.     <title>IE内存增长测试环境</title>  
  5.     <script src="jquery-1.10.2.js"></script>  
  6.     <script type="text/javascript">  
  7.     function test(){  
  8.         jQuery.ajaxSetup ({cache:false}) ;  
  9.         var v2="";  
  10.         v2+="<script src='jquery-1.10.2.js'/>";  
  11.         v2+="<script src='jquery-1.10.2.js'/>";  
  12.         v2+="<script src='jquery-1.10.2.js'/>";  
  13.         v2+="<script src='jquery-1.10.2.js'/>";  
  14.         v2+="<script src='jquery-1.10.2.js'/>";  
  15.         v2+="<script src='jquery-1.10.2.js'/>";  
  16.         v2+="<script src='jquery-1.10.2.js'/>";  
  17.         v2+="<script src='jquery-1.10.2.js'/>";  
  18.         v2+="<script src='jquery-1.10.2.js'/>";  
  19.         v2+="<script src='jquery-1.10.2.js'/>";  
  20.         v2+="<script src='jquery-1.10.2.js'/>";  
  21.         v2+="<body>加载内容1<br/></body>";  
  22.         $("#div").html($("#div").html()+v2);  
  23.     }  
  24.     </script>  
  25. </head>  
  26.   
  27. <body>  
  28.     <input type="button" value="load" onClick="test()"/>  
  29.     <div id="div"></div>  
  30. </body>  
  31. </html></span>  

 

 

在点击load按钮时,IE的内存不断增长,如果电脑的内存不足,很容易造成内存不足。俺用现在很常见的IE版本测试,IE7,IE8,IE9都这样的问题;俺又用几个jQuery比较新的版本测试,这样的问题还是存在。而用谷歌测试时,没有这样的问题,这说明这问题跟jQuery没有关系,而跟IE有关系。

呵呵,没有办法,俺为了了解甚至解决这个问题,决定跟踪jQuery源码,寻找解决问题之法。以下是IE9,jquery-1.10.2.js为样例测试.


 

以上是jQuery.html()方法的部分源码,因为value含有<script字样,所以代码将调用this.empty().append(value);

 

也就是说jquery 的append()方法也有这样的问题,更说明在某种情况下jQuery.append()和jQuery.html()是相等的.

 

继续跟踪jQuery .append()方法。

 


上面的代码很简单,应该没有什么问题,继续跟踪到jQuery.doManip()方法


俺开始以为是jQuery._evalUrl()这个地方是罪魁祸首,毕竟每次调用jQuery.html()或者jQuery.append()都有加载js,

而且在html页面把引用的

v2+="<script src='jquery-1.10.2.js'/>"改成v2+="<script src='jquery-1.10.2.j'/>"内存就没有增长了.但是发现不是,

而是jQuery.buildFrament()这个方法。

这就是一个很奇怪的问题了,继续跟踪buildFrament()方法


根据逐一排除法,发现有2个地方内存会不断增长,注意:上图上面标红增长不是很厉害,有少量内存回落或者不

回落,但是相当于下面标红,就显得其次了。

也就是说jQuery.merge()是造成内存增长的,没办法,继续跟踪jQuery.merge()方法。


这就是jQuery.merge()方法的所有的内容了,这个方法是把first,second2个数组合并到first一个数组。跟踪到这里,

这说明这块代码是内存增长的主要问题。跟踪first和second的值都很小,即使变量内存没有及时清除,也不可能

造成几十MB甚至上百MB的增长。


俺跟踪到这里,再根据v2+="<script src='jquery-1.10.2.js'/>"改成v2+="<script src='jquery-1.10.2.j'/>"内存不再增加的那个现象,说明jquery在创建标签<script的时候,包含的js内容对内存影响比较大,而且创建之后不会销毁。所以临时想到了一个取巧的方法,就是在赋值的时候把里面含有<script的js去掉,以下就是简单

写了一个js方法

 

[javascript] view plaincopy
 
  1. var result="";  
  2.     function ieAddScriptSrc(value){  
  3.         var scriptBegin=value.indexOf("<script");  
  4.         var srcIndex=value.indexOf("src");  
  5.         var scriptEnd=value.indexOf("\<\/script>");  
  6.         //包含<script>function testFun2(){alert('dd');}\<\/script><script src="jquery-1.10.2.js">\<\/script>  
  7.         if(scriptBegin>=0&&srcIndex>scriptBegin&&scriptEnd>srcIndex&&scriptEnd>srcIndex){  
  8.             var tempValue=value.substring(scriptBegin,scriptEnd+9);  
  9.             var srcValue="";  
  10.             var tempValueIndex1=tempValue.indexOf("src='");  
  11.             var tempValueIndex2=tempValue.indexOf('src="');  
  12.             if(tempValueIndex1>0){  
  13.                 var scriptEnd2=value.indexOf(".js'>\<\/script>");  
  14.                 if(scriptEnd2>srcIndex){  
  15.                     var scriptEnd1=tempValue.lastIndexOf(".js'")+3;  
  16.                     srcValue=tempValue.substring(tempValueIndex1+5,scriptEnd1);  
  17.                 }  
  18.             }else if(tempValueIndex2>0){  
  19.                 var scriptEnd2=value.indexOf('.js">\<\/script>');  
  20.                 if(scriptEnd2>srcIndex){  
  21.                     var scriptEnd2=tempValue.lastIndexOf('.js"')+3;  
  22.                     srcValue=tempValue.substring(tempValueIndex2+5,scriptEnd2);  
  23.                 }  
  24.             }  
  25.             if(srcValue){  
  26.                 var oHead = document.getElementsByTagName('HEAD').item(0);   
  27.                 var childNodes=oHead.childNodes;  
  28.                 var scrIsExist=false;  
  29.                 for(var i=0;i<childNodes.length;i++){  
  30.                     if(srcValue==childNodes[i].src){  
  31.                         scrIsExist=true;  
  32.                         break;  
  33.                     }  
  34.                 }  
  35.                 if(!scrIsExist){  
  36.                     var oScript= document.createElement("script");   
  37.                     oScript.type = "text/javascript";   
  38.                     oHead.appendChild( oScript);   
  39.                     oScript.src=srcValue;   
  40.                 }  
  41.                 result=result+ value.substring(0,scriptBegin);  
  42.             }else{  
  43.                 result=result+ value.substring(0,scriptEnd+9);  
  44.             }  
  45.             ieAddScriptSrc(value.substring(scriptEnd+9,value.length));  
  46.         }else{  
  47.             if(scriptBegin>=0&&scriptEnd>scriptBegin){  
  48.                 result=result+ value.substring(0,scriptEnd+9);  
  49.                 ieAddScriptSrc(value.substring(scriptEnd+9,value.length));  
  50.             }else{  
  51.                 result=result+value;  
  52.             }  
  53.         }  
  54.     }  


刷新再点击的时候,内存不再增长了。但是实际的问题根源还是没有找到,所以麻烦大哥们指点迷津,当然俺也会继续努力找到方法。如果有进展的话,在更新。

分享到:
评论

相关推荐

    jquery1.8依赖包

    3. **更好的事件处理**:这个版本对事件处理函数进行了改进,允许开发者更精确地控制事件绑定和解绑,减少了内存泄漏的可能性。 4. **CSS 选择器**:jQuery 1.8 支持更多的 CSS3 选择器,使得开发者可以利用更强大...

    jquery 实现的在线客服 插件

    此外,通过合理的DOM操作和事件绑定,可以提高插件性能,避免内存泄漏。 5. **扩展与自定义** 优秀的插件应该提供足够的扩展空间,允许开发者自定义更多功能,如表情支持、文件上传、历史记录查看等。可以设计插件...

    Jquery各个版本加手册

    例如,`.live()`方法在1.7版本中被引入,但在1.8中被废弃,因为它的性能问题和潜在的内存泄漏。取而代之的是,`.on()`方法成为处理动态元素事件的新标准,它提供了更灵活和高效的方式来绑定事件处理函数。 jQuery ...

    jQuery1.11.0_中文.chm

    - **内存泄漏问题修复**:在长时间运行的应用中,解决了可能存在的内存泄漏问题,提高了长期运行的稳定性。 #### 3. 兼容性增强 - **IE8及更高版本的兼容性**:确保jQuery 1.11.0在Internet Explorer 8及以上版本中...

    jquery1.7 及jquery手册

    3. **.live()方法的弃用**:由于性能和内存泄漏问题,`.live()`方法被弃用,推荐使用`.on()`来替代,以实现事件委托。 4. **更好的浏览器兼容性**:jQuery 1.7致力于提高对各种浏览器的兼容性,尤其是对老版本IE的...

    jquery1.5.0

    7. **性能改进**:jQuery 1.5在内存管理和事件处理方面进行了优化,减少了内存泄漏的可能性,并提升了事件绑定与解绑的效率。此外,对IE浏览器的兼容性也有了显著提升。 总的来说,jQuery 1.5是一个强大且易用的...

    jQuery专栏,一些资源

    10. **性能优化(Performance Optimization)**:理解`$(document).ready()`与`$(window).load()`的区别,使用高效的元素选择器,避免内存泄漏,以及正确使用事件委托,都是提高jQuery应用性能的关键。 这个jQuery...

    JQuery源码注释

    jQuery源码中包含了许多性能优化策略,如缓存查找结果、避免内存泄漏、减少DOM操作等。注释中会详细讲解这些技巧,并提醒开发者在实际开发中应用。 8. **兼容性处理** 为了适应各种浏览器环境,jQuery进行了大量...

    JQuery API

    2. **DOM操作**:jQuery 提供了简便的DOM操作接口,如`$(selector).html()`, `$(selector).append()` 和 `$(selector).remove()`。1.6版增强了这些方法,提高了性能并减少了内存泄漏的可能性。 3. **事件处理**:...

    1.4.2jquery中文手册

    - 学习如何避免内存泄漏,合理使用事件解绑,以及优化选择器以提高性能。 - 使用`.noConflict()`防止与其他库的命名冲突。 8. **兼容性与版本差异** - 理解jQuery对不同浏览器的兼容策略,尤其是对老版本IE的...

    jQuery学习PPT

    - 使用`$().each()`代替循环遍历,避免内存泄漏,提高性能。 8. **实战应用** - PPT中可能包含实际案例,如导航栏的响应式设计、图片轮播、表单验证等,帮助理解jQuery的实际应用场景。 这份“jQuery学习PPT”...

    jQuery2012QQ商城焦点图效果

    8. **优化性能**:合理使用事件代理,避免内存泄漏,以及优化图片加载,如延迟加载未进入视口的图片,提升页面加载速度。 为了实现"jQuery2012QQ商城焦点图效果",开发者可能结合了上述技术,创建了一个包含以下...

    jQuery适合风景展现幻灯片代码.zip

    7. **优化性能**:合理使用事件委托,避免内存泄漏,并考虑使用`$(document).ready()`和`$(window).load()`来确保代码在页面完全加载后执行。 8. **兼容性测试**:确保代码在主流浏览器(如Chrome, Firefox, Safari...

    twitter上发现了<jQuery Performance Rules>这篇文章,

    4. **内存分析**: 分析内存分配,查找内存泄漏,通过对象分配视图和垃圾收集日志来优化内存管理。 5. **线程分析**: 查看线程状态,定位死锁和阻塞,帮助解决多线程问题。 6. **数据库监控**: 检查SQL语句的执行...

    PHP下ajax跨域的解决方案之window.name实例分析

    值得注意的是,`window.name`能够存储大量数据(在IE和Firefox下可以达到32MB左右),这使得它成为一种可行的跨域数据传输方式。然而,这种方法也有其局限性,例如,它依赖于`iframe`,可能受到同源策略的限制,并且...

Global site tag (gtag.js) - Google Analytics