2008-03-24
fighting with IE memory leak
关键字: ie6 内存泄露 memory leak
在某个Ajax项目中使用到了Adobe Spry框架。
在项目部署测试中,发现有内存泄露。仔细检查了所有的代码,发现该注意的地方都已经清理过,一时找不到原因。最后突发奇想是不是用到的Spry框架的问题?用测试工具详细分析后表明,Spry的MenuBar组件在IE6下有内存泄露。晕,让Adobe的名号害惨了项目组的同志们,即使最新的1.6.1版本也不例外。最后分析代码表明,这还是那个IE6JS引擎与DOM引擎相互分离的老BUG了,当dom元素绑定到的事件响应函数引用到自身的时候。在page unload的时候,该元素就会成为孤儿,它占用的内存就不会被系统所回收。
经过测试,这个全局的菜单每次会有56个泄露的节点,占用内存200k左右。当页面浏览次数增加时,甚至会有数十M的内存泄露!
找到了问题的所在,那么解决起来就很容易了。hack部分代码,解决内存泄露。项目顺利验收...
在注册事件响应时,把匿名函数绑定在该元素上
增加一个clearLeak方法,在onload事件中清除这些绑定。
最后在构造方法中,绑定menubar实例与清除函数。完成。
参考文章:
JScript Memory Leaks
Understanding and Solving Internet Explorer Leak Patterns
Closures and IE Circular References
在项目部署测试中,发现有内存泄露。仔细检查了所有的代码,发现该注意的地方都已经清理过,一时找不到原因。最后突发奇想是不是用到的Spry框架的问题?用测试工具详细分析后表明,Spry的MenuBar组件在IE6下有内存泄露。晕,让Adobe的名号害惨了项目组的同志们,即使最新的1.6.1版本也不例外。最后分析代码表明,这还是那个IE6JS引擎与DOM引擎相互分离的老BUG了,当dom元素绑定到的事件响应函数引用到自身的时候。在page unload的时候,该元素就会成为孤儿,它占用的内存就不会被系统所回收。
经过测试,这个全局的菜单每次会有56个泄露的节点,占用内存200k左右。当页面浏览次数增加时,甚至会有数十M的内存泄露!
找到了问题的所在,那么解决起来就很容易了。hack部分代码,解决内存泄露。项目顺利验收...
在注册事件响应时,把匿名函数绑定在该元素上
Spry.Widget.MenuBar.prototype.addEventListener = function(element, eventType, handler, capture)
{
try
{
if (element.addEventListener)
{
element.addEventListener(eventType, handler, capture);
}
else if (element.attachEvent) //IE6 needs more to handle memory
{
element.attachEvent('on' + eventType, handler);
if(!element._handlers) element._handlers = [];
element._handlers['on' + eventType] = handler;
}
}
catch (e) {}
}
增加一个clearLeak方法,在onload事件中清除这些绑定。
Spry.Widget.MenuBar.clearLeak = function(menu)
{
if(!Spry.is.ie)return;
alert('reged with' + menu.element.id);
window.attachEvent('onunload', function(){
//alert('recycling...');
var recycler = document.createElement('div');
var element = menu.element;
loopLeak(element);
function loopLeak(object)
{
var children = object.childNodes;
if(children.length > 0)
{
for(var i in children)
{
var child = children[i];
if(child && child.nodeType == 1)loopLeak(child);
}
}
if(object && object._handlers)
{
for(var index in object._handlers)
{
var handler = object._handlers[index];
object.detachEvent(index, handler);
}
var a = object.attributes, i, l, n;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
n = a[i].name;
if (typeof object[n] === 'function') {
object[n] = null;
}
}
}
object._handlers = null;
}
}
//alert('recycling...done');
element = null;
});
}
最后在构造方法中,绑定menubar实例与清除函数。完成。
Spry.Widget.MenuBar.prototype.init = function(element, opts)
{
//...ommitted
if(Spry.is.ie)
{
//...
Spry.Widget.MenuBar.clearLeak(this);
}
}
};
参考文章:
JScript Memory Leaks
Understanding and Solving Internet Explorer Leak Patterns
Closures and IE Circular References
- 22:04
- 浏览 (284)
- 评论 (0)
- 分类: javascript
- 相关推荐
发表评论
- 浏览: 7698 次

- 详细资料
搜索本博客
最近加入圈子
链接
最新评论
-
淘宝的UED招聘试题,来试 ...
好像上边提供的下载程序运行不了啊
-- by popper -
淘宝的UED招聘试题,来试 ...
没有时间写文字blog。。。昨晚通宵看了Spry的技术文档,发现adobe还真强 ...
-- by boin -
淘宝的UED招聘试题,来试 ...
呵呵... 看来我是乱做的啦. 而且我留的blog是我的文字blog 不是技术b ...
-- by 520hacker -
省市联动二级菜单
hcfhfg
-- by yoyo.awen -
扩展prototype,增加良好 ...
他打错了吧,应该是服务器返回信息更新页面那个id
-- by huanguuq






评论排行榜