精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-03-20
Ext2.02事件机制缺陷分析,以及解决方案 http://fins.iteye.com/blog/173818 EXT的destroy方法是不是存在漏洞? http://fins.iteye.com/blog/173218 测试使用工具见 http://fins.iteye.com/blog/172891 解决这一问题后我们可以发现, 依然存在内存无法释放的问题. 分析后得出ext的又一个重大缺陷 还是拿一个最最简单的window做例子 win=new Ext.Window({title:" 窗口 ", width:400, draggable : false, shadow : false, resizable : false, shim :false, autoDestroy : true, height:300}); 一个干净的页面, 生成上面那个窗口,然后再关闭, 用sIEve查看, 会发现存在很多无法被释放的 ext生成的孤立节点 大家可以注意看一下那些节点的 class ,可以发现如下两个(还有更多,我只是拿他们举例子). x-dlg-focus x-window-bwrap 也就是说,这两个节点没有被正确的销毁. 跟踪代码可以发现 这两个节点分别对应 window对象的 this.focusEl this.bwrap 为什么没有被正确的删除呢? 继续跟踪 跟踪所有 window层次结构上的所有类的 destroy beforeDestroy onDestroy 方法 可以看到 ,从来没有显示的调用过 消除他们的方法. 看来我们需要自己手动来销毁他们了. 于是可以修改 Window 的 beforeDestroy 方法: Ext.Window.prototype.beforeDestroy = function(){ Ext.destroy( this.focusEl, // 新增 this.bwrap, // 新增 this.resizer, this.dd, this.proxy, this.mask ); Ext.Window.superclass.beforeDestroy.call(this); } 测试后发现, 依然无法删除那两个节点. 不死心, 继续!!! 再修改 Ext.Window.prototype.beforeDestroy = function(){ Ext.destroy( this.focusEl, // 新增 this.bwrap, // 新增 this.resizer, this.dd, this.proxy, this.mask ); Ext.Window.superclass.beforeDestroy.call(this); this.focusEl=null; // 新增 this.bwrap=null; // 新增 } 注意 由于 this.bwrap 是window从panel里继承来的, 所以this.bwrap其实应该通过修改panel的代码来消除 我在这里用偷懒的方式 是为了可以用尽量简短的代码来说明问题 再测试, ok 那两个节点没了!! ================================= 综上所述,我们可以得到如下结论: Ext的作者为各个组件提供的 destroy方法存在严重缺陷. 缺少对一些元素必要的 销毁动作, 同时 没有对属性赋值为 null ,使得浏览器无法回收多余的节点. 页面越复杂 这个问题越严重. 解决办法只能是一个个组件看 看看哪些地方有遗漏 然后进行修补.能在基类中修补尽量修补. 同时 应该为组件增加 afterDestroy方法, 在里面对必要的属性进行赋值为null的操作. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-03-20
呵呵,果然有发现啊,不枉我这几天一直在跟你。呵呵。最近公司的东西就应用到EXT,效率真是要命啊。我就知道Ext内部肯定有问题的。
|
|
返回顶楼 | |
发表时间:2008-03-20
这几天看了你的几篇文章,很有收获
|
|
返回顶楼 | |
发表时间:2008-03-23
最好反馈给ext社区。
|
|
返回顶楼 | |
发表时间:2008-04-23
panel本身问题就很多。 Panel.js中643行 this.header.unselectable();
查看Element.js 1946行 this.swallowEvent("selectstart", true); this.applyStyles("-moz-user-select:none;-khtml-user-select:none;"); 第一句swallowEvent给header加入了一个事件,但是panel destory的时候并没有释放. 第二句太诡异,加入这句也会导致header节点不释放. 解决办法: Element.js中unselectable方法注释掉这行 //this.applyStyles("-moz-user-select:none;-khtml-user-select:none;"); Panel.js中 beforeDestroy : function(){ if(this.header)this.header.removeAllListeners(); Ext.Element.uncache( this.header, this.tbar, this.bbar, this.footer, this.body ); } window中也发现很多问题.回头再贴. 猜测很多组件destroy不释放一些dom的绑定事件. |
|
返回顶楼 | |
发表时间:2008-04-28
fins,你好.!
关于ext2.0我有一些问题想请教你.能否留个联系方式,MSN或者QQ,谢谢了! |
|
返回顶楼 | |
发表时间:2008-04-28
ext我也不是很熟 只是凑巧研究了他里面的一些代码
但是对他的认识还不够深 你不妨把问题写出来 让大家一起来帮你 |
|
返回顶楼 | |
发表时间:2008-04-28
恩.好的.
多的我就不说了,因为我也是刚学习这东东, 目前的问题: 也是关于ext内存的问题. 我用你介绍的工具测试了一下我现在所做的项目的其中一个页面,并没有发现有内存泄露的节点. 但是我想怎样才能真正达到内存释放的效果呢?因为我现在产生一个window,关闭一个window的时候,内存还是会增加,但是工具里又没有显示有内存泄露的节点。按道理应该会释放掉window打开时所产生的内存啊。 而且我发现改不改基类似乎都没有什么区别,因为在用工具测试的时候两者都不会产生内存泄露节点。 我用的ext2.02。 请指教。 |
|
返回顶楼 | |
发表时间:2008-04-28
哦 这个啊 可以重写 window的 destroy方法 删除那些没有被移除的节点
同时 重写 ext的时间注销机制 |
|
返回顶楼 | |
发表时间:2008-04-28
恩,好的。谢谢了。
回头我来试试,不懂的地方在请教你。 |
|
返回顶楼 | |