MagicAjax中的内存泄漏
来源:互联网 发布:ubuntu kde kde 编辑:程序博客网 时间:2024/06/05 23:45
之前用 MagicAjax 做了一个项目,已经上线了两三个月,最近客户说它经常会把 IE 弄死,找了好几天,没有发现程序有什么问题,但是浏览器偶尔是会死掉(占 CPU 50%-双核),程序都找完了就去找 MagicAjax 的代码,意外发现了 MagicAjax 的 JS 中有一个内存泄漏的 BUG (不过和我的问题无关,因为我改了后, IE 还是会死),现在说一下这个 BUG 供使用 MagicAjax 的朋友参考一下.
在 AjaxCallObject 类的方法 DoAjaxCall 有这样一段代码:
Code
1 if( this.XmlHttp )
2 {
3 if (waitElement)
4 {
5 waitElement.style.visibility = 'visible';
6 MoveWaitElement();
7 }
8
9 var oThis = this;
10 __AJAXCboList.push(oThis);
11 AJAXCbo = new AjaxCallObject();
12
13 if (__bTracing)
14 {
15 this.CreateTracingWindow();
16 this.TraceSentData(theData);
17 }
18
19 if( this.XmlHttp.readyState == 4 || this.XmlHttp.readyState == 0 )
20 {
21 if ( ! ajaxCallType || ajaxCallType.toLowerCase() != "sync")
22 {
23 // Asynchronous
24 this.XmlHttp.open("POST", thePage, true);
25 this.XmlHttp.onreadystatechange = function(){ oThis.ReadyStateChange(); };
26 this.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
27 this.XmlHttp.send(theData);
28 }
29 else
30 {
31 // Synchronous
32 // Use a timeout so that the screen refreshes before getting stack waiting the AjaxCall.
33 window.setTimeout(
34 function()
35 {
36 oThis.XmlHttp.open("POST", thePage, false);
37 oThis.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
38 oThis.XmlHttp.send(theData);
39
40 if( oThis.XmlHttp.status == 200 && oThis.XmlHttp.statusText == "OK" )
41 oThis.OnComplete(oThis.XmlHttp.responseText, oThis.XmlHttp.responseXML);
42 else
43 oThis.OnError(oThis.XmlHttp.status, oThis.XmlHttp.statusText, oThis.XmlHttp.responseText);
44 }, 1);
45 }
46 }
47 }
1 if( this.XmlHttp )
2 {
3 if (waitElement)
4 {
5 waitElement.style.visibility = 'visible';
6 MoveWaitElement();
7 }
8
9 var oThis = this;
10 __AJAXCboList.push(oThis);
11 AJAXCbo = new AjaxCallObject();
12
13 if (__bTracing)
14 {
15 this.CreateTracingWindow();
16 this.TraceSentData(theData);
17 }
18
19 if( this.XmlHttp.readyState == 4 || this.XmlHttp.readyState == 0 )
20 {
21 if ( ! ajaxCallType || ajaxCallType.toLowerCase() != "sync")
22 {
23 // Asynchronous
24 this.XmlHttp.open("POST", thePage, true);
25 this.XmlHttp.onreadystatechange = function(){ oThis.ReadyStateChange(); };
26 this.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
27 this.XmlHttp.send(theData);
28 }
29 else
30 {
31 // Synchronous
32 // Use a timeout so that the screen refreshes before getting stack waiting the AjaxCall.
33 window.setTimeout(
34 function()
35 {
36 oThis.XmlHttp.open("POST", thePage, false);
37 oThis.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
38 oThis.XmlHttp.send(theData);
39
40 if( oThis.XmlHttp.status == 200 && oThis.XmlHttp.statusText == "OK" )
41 oThis.OnComplete(oThis.XmlHttp.responseText, oThis.XmlHttp.responseXML);
42 else
43 oThis.OnError(oThis.XmlHttp.status, oThis.XmlHttp.statusText, oThis.XmlHttp.responseText);
44 }, 1);
45 }
46 }
47 }
其中 __AJAXCboList 是一个数组,在每次提交 ( POST ) 数据前会把当前对象放入数组中,并新建一个对象供下一个提交( POST )使用.当在使用异步提交时,处理服务器返回数据的方法如下 :
Code
1 AjaxCallObject.prototype.ReadyStateChange = function()
2 {
3 if( this.XmlHttp.readyState == 1 )
4 {
5 this.OnLoading();
6 }
7 else if( this.XmlHttp.readyState == 2 )
8 {
9 this.OnLoaded();
10 }
11 else if( this.XmlHttp.readyState == 3 )
12 {
13 this.OnInteractive();
14 }
15 else if( this.XmlHttp.readyState == 4 )
16 {
17 if( this.XmlHttp.status == 0 )
18 this.OnAbort();
19 else if( this.XmlHttp.status == 200 )
20 this.OnComplete(this.XmlHttp.responseText, this.XmlHttp.responseXML);
21 else
22 this.OnError(this.XmlHttp.status, this.XmlHttp.statusText, this.XmlHttp.responseText);
23
24 // Remove this AJAXCbo from the list
25 for (var i=0; i < __AJAXCboList.length; i++)
26 if (__AJAXCboList[i] == this)
27 {
28 __AJAXCboList[i].XmlHttp = null;
29 __AJAXCboList.splice(i, 1);
30 break;
31 }
32 }
33 }
1 AjaxCallObject.prototype.ReadyStateChange = function()
2 {
3 if( this.XmlHttp.readyState == 1 )
4 {
5 this.OnLoading();
6 }
7 else if( this.XmlHttp.readyState == 2 )
8 {
9 this.OnLoaded();
10 }
11 else if( this.XmlHttp.readyState == 3 )
12 {
13 this.OnInteractive();
14 }
15 else if( this.XmlHttp.readyState == 4 )
16 {
17 if( this.XmlHttp.status == 0 )
18 this.OnAbort();
19 else if( this.XmlHttp.status == 200 )
20 this.OnComplete(this.XmlHttp.responseText, this.XmlHttp.responseXML);
21 else
22 this.OnError(this.XmlHttp.status, this.XmlHttp.statusText, this.XmlHttp.responseText);
23
24 // Remove this AJAXCbo from the list
25 for (var i=0; i < __AJAXCboList.length; i++)
26 if (__AJAXCboList[i] == this)
27 {
28 __AJAXCboList[i].XmlHttp = null;
29 __AJAXCboList.splice(i, 1);
30 break;
31 }
32 }
33 }
可见当提交( POST )完成后,会给之前放入的 AJAXCbo 对象赋空值并从数组 __AJAXCboList 中删除,以便浏览器回收对象,这里没有什么问题,有问题的是当使用同步提交( POST )时, MagicAjsx 并没有使用 ReadyStateChange 方法来处理回发的数据,而是用直接写的方法来处理的:
1 // Synchronous
2 // 使用定时器,以便显示那个黑黑的Loading层,可见MagicAjax中的同步不是真正的同步
3 window.setTimeout(
4 function()
5 {
6 oThis.XmlHttp.open("POST", thePage, false);
7 oThis.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
8 oThis.XmlHttp.send(theData);
9
10 if( oThis.XmlHttp.status == 200 && oThis.XmlHttp.statusText == "OK" )
11 oThis.OnComplete(oThis.XmlHttp.responseText, oThis.XmlHttp.responseXML);
12 else
13 oThis.OnError(oThis.XmlHttp.status, oThis.XmlHttp.statusText, oThis.XmlHttp.responseText);
14 }, 1);
2 // 使用定时器,以便显示那个黑黑的Loading层,可见MagicAjax中的同步不是真正的同步
3 window.setTimeout(
4 function()
5 {
6 oThis.XmlHttp.open("POST", thePage, false);
7 oThis.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
8 oThis.XmlHttp.send(theData);
9
10 if( oThis.XmlHttp.status == 200 && oThis.XmlHttp.statusText == "OK" )
11 oThis.OnComplete(oThis.XmlHttp.responseText, oThis.XmlHttp.responseXML);
12 else
13 oThis.OnError(oThis.XmlHttp.status, oThis.XmlHttp.statusText, oThis.XmlHttp.responseText);
14 }, 1);
当提交( POST )完成后,__AJAXCboList数组中将始终保留这个 AJAXCbo 对象.我测试过,没有其它的地方会释放里面的数据,除非刷新页面.我后来把它改成也用 ReadyStateChange 方法来处理就没有这个问题了.
1 window.setTimeout(
2 function()
3 {
4 oThis.XmlHttp.open("POST", thePage, false);
5 oThis.XmlHttp.onreadystatechange = function(){ oThis.ReadyStateChange(); };
6 oThis.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
7 oThis.XmlHttp.send(theData);
8
9 //if( oThis.XmlHttp.status == 200 && oThis.XmlHttp.statusText == "OK" )
10 // oThis.OnComplete(oThis.XmlHttp.responseText, oThis.XmlHttp.responseXML);
11 //else
12 // oThis.OnError(oThis.XmlHttp.status, oThis.XmlHttp.statusText, oThis.XmlHttp.responseText);
13 }, 1);
2 function()
3 {
4 oThis.XmlHttp.open("POST", thePage, false);
5 oThis.XmlHttp.onreadystatechange = function(){ oThis.ReadyStateChange(); };
6 oThis.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
7 oThis.XmlHttp.send(theData);
8
9 //if( oThis.XmlHttp.status == 200 && oThis.XmlHttp.statusText == "OK" )
10 // oThis.OnComplete(oThis.XmlHttp.responseText, oThis.XmlHttp.responseXML);
11 //else
12 // oThis.OnError(oThis.XmlHttp.status, oThis.XmlHttp.statusText, oThis.XmlHttp.responseText);
13 }, 1);
- MagicAjax中的内存泄漏
- J2ME中的内存泄漏
- JavaScript 中的内存泄漏
- Bfd中的内存泄漏
- J2ME中的内存泄漏
- J2ME中的内存泄漏
- java中的内存泄漏
- java中的内存泄漏
- java中的内存泄漏
- MyGUI中的内存泄漏
- Java中的内存泄漏
- java中的内存泄漏
- android中的内存泄漏
- Java中的内存泄漏
- java中的内存泄漏
- Android中的内存泄漏
- Java中的内存泄漏
- Java中的内存泄漏
- “解雇通知”怎么说
- 使用C++访问Google API
- Enterprise Library 4.1 + Unity Application Block 1.2 December 2008
- 算法的力量李开复
- Christmas wraps up another year of surprises
- MagicAjax中的内存泄漏
- Love is Special
- SuperMap Object 读取SQL数据库中的地图
- c#常用的技巧
- 如何评估工作offer
- DWR2.0 util.js方法说明
- .NET 实现Hashlist--可以排序的哈希表
- bboss persistent连接池启动过程中报jndi 查找异常处理
- NET Managed Provider for Oracle 在 US7ASCII 中文乱码