2008年4月30日星期三

内存泄漏的问题

近来项目发现内存泄漏问题严重,花了两天多时间才解决

修改前,实时分析雷达图每 10 秒刷新一次,内存同时增长 2M 左右
问题主要在两个地方,第一个地方占用内存最大,修改完成后,内存的增长速度降到 每分钟增长 2M 左右,第二个地方修改完成后,现在我本机测试已经看不出明显的内存增长了

内存泄漏的原因有多种,但最主要的泄漏就是 DOM 域与 js 域相互引用以及内部函数,现在我们修改的地方也是这种情况,其实如果不是经常刷新,应该问题不大,只要重启 IE 就可以释放,但我们需要不停的刷新,所以问题比较明显.

比如下面的代码:

代码一(内部函数):
function AttachEvents(element)
{
// This structure causes element to ref ClickEventHandler
element.attachEvent("onclick", ClickEventHandler);

function ClickEventHandler()
{
// This closure refs element
}
}
}

//调用此函数就会发生泄漏
function SetupLeak()
{
AttachEvents(document.getElementById("LeakedDiv"));
}


代码二(dom 跟 js 相互引用):
document.createElement("");
或者:
document.createElement("");
fuction a(){...}

1. WEB-INF/pages/sim/analyse/view/sceneEventList.jsp
有两处代码需要修改,这两处代码类似,下面是其中一处的代码及修改后的代码:

原代码:
$("headerContainer").childElements().invoke("remove");
$("headerContainer").innerHTML = headerHTML;
现代码:
$("headerContainer").innerHTML = null;
$("headerContainer").innerHTML = headerHTML;

2. web/common/scrollTable.jsp
在函数 initColumnResizer(...) 中内部建了函数

原代码:
var resizeBar = document.createElement('DIV');
resizeBar.style.backgroundColor = 'transparent';
.......
resizeBar.onmouseout = function() {
this.style.cursor = 'default';
};
.......

问题主要就在类似于 resizeBar.onmouseout = function(){...} 这样的代码上,DOM 对象 resizeBar 直接定义了函数 function,此处类似的函数一共是 6 个

解决方法就是将这些函数单独拿出来,然后再引用

现代码:

在 initColumnResizer 函数外新定义函数 mouseout 等函数,如下:

function mouseout(){
.......
}

然后在 initColumnResizer 函数中原来引用这些函数的地方用下面的代码替换:
rezeBar = null;
resizeBar = document.createElement('DIV');
resizeBar.style.backgroundColor = 'transparent';
.......

resizeBar.onmouseover = mouseover;
resizeBar.onmouseout = mouseout;
resizeBar.onclick = mouseclick;
resizeBar.onmousedown = mousedown;
resizeBar.onmousemove = mousemove;
resizeBar.onmouseup = mouseup;

没有评论: