Ext的destroy机制引起的内存问题的分析( 二 )

前几天讨论了一下 ext的 Destroy机制引起的内存问题 发现出现问题的核心点 是 element.removeAllListeners 方法. 相关讨论见:

Ext2.02事件机制缺陷分析,以及解决方案
http://fins.iteye.com/blog/173818

EXT的destroy方法是不是存在漏洞?
http://fins.iteye.com/blog/173218


测试使用工具见
http://fins.iteye.com/blog/172891


解决这一问题后我们可以发现, 依然存在内存无法释放的问题.
分析后得出[size=large][color=red]ext的又一个重大缺陷[/color][/size]

还是拿一个最最简单的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; // 新增

}


[color=red]注意[/color] [color=blue]由于 this.bwrap 是window从panel里继承来的, 所以this.bwrap其实应该通过修改panel的代码来消除
我在这里用偷懒的方式 是为了可以用尽量简短的代码来说明问题[/color]


再测试, ok 那两个节点没了!!


=================================
综上所述,我们可以得到如下结论:
Ext的作者为各个组件提供的 [color=red]destroy方法存在严重缺陷[/color].
缺少对一些元素必要的 销毁动作, 同时 没有对属性赋值为 null ,使得浏览器无法回收多余的节点.

页面越复杂 这个问题越严重.
解决办法只能是一个个组件看 看看哪些地方有遗漏 然后进行修补.能在基类中修补尽量修补.
同时 应该为组件增加 afterDestroy方法, 在里面对必要的属性进行赋值为null的操作.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值