昨晚,为了验证网易博客中计算点击量的Flash如何工作,一直刷新blog,大约进行了二三十次。早晨,关机前,觉得机器有些慢,赫然发现IE占用了接近200M内存,关闭其它窗口,只剩网易博客,资源占用依然超过了170M。
忽然想到了Javascript,想到了Ajax,是否因为Javascript中某些对象无法被回收造成的?一夜没睡,实在没精力再去分析网易的Javascript,百度一下,发现了以下内容。先贴这里,醒来再验证。
创建XMLHttpRequest对象的方式有两种:一是作为全局变量,二是作为局部变量,那么这两种方式下的AJAX对象的生命周期如何?考虑这个问题的原因是,如果页面不停的使用不同XMLHttpRequest对象请求,并且AJAX对象的生命周期是全局的,那么显然内存最终会被耗尽!
解决这个问题的方法似乎只能以局部变量方式创建XMLHttpRequest对象,但是局部创建的AJAX对象占用的内存什么时候被回收?请看下面的代码,是否creatConnect中send调用后就被回收?如果是这样那就糟糕了,因为当服务器有结果返回时再也找到不到ajax对象的readyState、responseText等属性,因此结论是浏览器不知道什么时候该回收ajax对象占用的内存,因为它永远不知道回调函数会什么时候被调用!按照这个结论,如果在一个页面不停的创建局部的AJAX对象,它是会吃光内存的!
继续使用下面的例子进行测试,但是为了让测试结果更明显些将obj[i].i=“f“;中“f“变为大段的文本(obj本来也是局部变量,当函数调用完就会被销毁,但是它在这个函数中也许不一样)。
我的测试结果(点击test1)是它似乎真的会吃光内存!大概不到一个小时的时间IE线程占用内存达到了300多M,后来系统变慢以至很难响应。(由于PC会使用虚拟内存,所以将虚拟内存调到3-400M,同时将系统的空间搞到只剩下1、200M以下,这样效果会更快些,否则系统会使用页面文件)
不知道我的测试方法和测试结果是否正确,如果是的话,哪位高人有比较好的方法来解决这样的内存问题?因为在某些情况下web应用可能真的需要不停的创建AJAX对象,谢谢!
function creatConnect(url)
{
var ajax=null;
if(window.ActiveXObject)
{
ajax=new ActiveXObject(“Microsoft.XMLHTTP“);
}
else if(window.XMLHttpRequest)
{
ajax=new XMLHttpRequest();
}
ajax.open(“GET“,url,true);
var obj=new Array();
for(var i=0;i<100;i++)
{
obj[i]=new Object();
obj[i].i=“f“;
}
ajax.onreadystatechange=function (){
if(ajax.readyState==4)
{
document.getElementById(“show“).innerHTML=(new Date()).getTime();
}
};
ajax.send(null);
}
var timer=null;
function test1()
{
clearTimeout(timer);
timer=null;
creatConnect(“test.htm“);
timer=setTimeout(“test1()“,1);
}
function test2()
{
clearTimeout(timer);
timer=null;
var obj=new Array();
for(var i=0;i<100;i++)
{
obj[i]=new Object();
obj[i].i=“f“;
}
document.getElementById(“show“).innerHTML=(new Date()).getTime();
timer=setTimeout(“test2()“,1);
}
function stop()
{
clearTimeout(timer);
timer=null;
}