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

web_jquery 专栏收录该内容
1 篇文章 0 订阅

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

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


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


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

<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>IE内存增长测试环境</title>
	<script src="jquery-1.10.2.js"></script>
	<script type="text/javascript">
	function test(){
		jQuery.ajaxSetup ({cache:false}) ;
		var v2="";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<script src='jquery-1.10.2.js'/>";
		v2+="<body>加载内容1<br/></body>";
		$("#div").html($("#div").html()+v2);
	}
	</script>
</head>

<body>
	<input type="button" value="load" onClick="test()"/>
	<div id="div"></div>
</body>
</html>

在点击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方法

var result="";
	function ieAddScriptSrc(value){
		var scriptBegin=value.indexOf("<script");
		var srcIndex=value.indexOf("src");
		var scriptEnd=value.indexOf("\<\/script>");
		//包含<script>function testFun2(){alert('dd');}\<\/script><script src="jquery-1.10.2.js">\<\/script>
		if(scriptBegin>=0&&srcIndex>scriptBegin&&scriptEnd>srcIndex&&scriptEnd>srcIndex){
			var tempValue=value.substring(scriptBegin,scriptEnd+9);
			var srcValue="";
			var tempValueIndex1=tempValue.indexOf("src='");
			var tempValueIndex2=tempValue.indexOf('src="');
			if(tempValueIndex1>0){
				var scriptEnd2=value.indexOf(".js'>\<\/script>");
				if(scriptEnd2>srcIndex){
					var scriptEnd1=tempValue.lastIndexOf(".js'")+3;
					srcValue=tempValue.substring(tempValueIndex1+5,scriptEnd1);
				}
			}else if(tempValueIndex2>0){
				var scriptEnd2=value.indexOf('.js">\<\/script>');
				if(scriptEnd2>srcIndex){
					var scriptEnd2=tempValue.lastIndexOf('.js"')+3;
					srcValue=tempValue.substring(tempValueIndex2+5,scriptEnd2);
				}
			}
			if(srcValue){
				var oHead = document.getElementsByTagName('HEAD').item(0); 
				var childNodes=oHead.childNodes;
				var scrIsExist=false;
				for(var i=0;i<childNodes.length;i++){
					if(srcValue==childNodes[i].src){
						scrIsExist=true;
						break;
					}
				}
				if(!scrIsExist){
					var oScript= document.createElement("script"); 
					oScript.type = "text/javascript"; 
					oHead.appendChild( oScript); 
					oScript.src=srcValue; 
				}
				result=result+ value.substring(0,scriptBegin);
			}else{
				result=result+ value.substring(0,scriptEnd+9);
			}
			ieAddScriptSrc(value.substring(scriptEnd+9,value.length));
		}else{
			if(scriptBegin>=0&&scriptEnd>scriptBegin){
				result=result+ value.substring(0,scriptEnd+9);
				ieAddScriptSrc(value.substring(scriptEnd+9,value.length));
			}else{
				result=result+value;
			}
		}
	}

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

  • 0
    点赞
  • 1
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

dwc_fly

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值