- 浏览: 2612782 次
- 性别:
- 来自: 小胖儿的大城
文章分类
最新评论
-
ni4wangba0:
ni4wangba0 写道亲测,算法有问题。对不起,其实是我自 ...
谈谈"求线段交点"的几种算法(js实现,完整版) -
ni4wangba0:
亲测,算法有问题。
谈谈"求线段交点"的几种算法(js实现,完整版) -
kers007:
苹果不让Webapp 在appstore 里发布,我不知道对 ...
苹果真的要在 AppStore 里封杀 WebApp 吗? -
striveandlive:
fins = js大牛
[原创]GT-Template, 一个超轻量级的js模板工具. -
AlwaysYang:
基础扎实的才能行走天下。
关于body的"大小"在ie和ff下的一些基础知识
EXT的destroy方法是不是存在漏洞?销毁的不彻底?
利用
http://fins.iteye.com/blog/172891
提到的工具,在IE下对EXT进行测试
只是一个简单的页面,页面内只是简单的定义一个简单的window ,如下
关闭这个window时 产生很多ie无法自动回收的孤立结点
每次创建 关闭 创建 关闭 ....
孤立结点都会越来越多
也许这是IE的错 但是EXT不应该忽视IE的 毕竟IE的占有率在那里放着呢
还请大家帮忙分析分析
我看了一下 window/panel的destroy方法似乎确实存在着一些缺陷啊
我重写了 window的destroy方法,效果提升一些,一些顽固结点可以删除了
但是还剩下一下更加顽固的结点无法删除
这个问题如果不弄明白, 在一个复杂的ext页面内,随着操作的增加 内存消耗也将越来越大.
deskto那个例子里的 窗口 大家打开关闭打开关闭 几个来回之后内存占用就会达到6 7十M了.
我怀疑 ext的各个组件的destroy方法内部的实现考虑的不够全面, 销毁内容 和销毁顺序 不当造成部分元素无法销毁.
希望大家能够一起讨论分析一下ext的问题到底处在哪里
注释掉恐怕不行,因为实际有些地方使用了el.un(...,fn)的方式停止监听,在ext的论坛上搜索_handlers destory,可以找到一篇11份的帖子提到这个问题,ext的开发人员在一些相关的回答中隐约说了要解决这个问题。假如ext本身保证了以非global function作为监听器,或者我们小心点去避免这个问题,呵呵。
发现问题在于ext的 wrap function,就是listener是global的话就会有问题。
见 EventManager.js的140行:
这里给传入的listener加了_handlers属性,stopLisener负责清除,那么就能正确的处理。
但是destroy直接调用了E.purgeElement...,这个方法好像没办法看到原来的listen,所以,没办法正确的清除_handlers,而_handlers引用了element
但其实ext已经用传入的function包装了一个新的function,然后才绑定到节点去。
利用
http://fins.iteye.com/blog/172891
提到的工具,在IE下对EXT进行测试
只是一个简单的页面,页面内只是简单的定义一个简单的window ,如下
var win=new Ext.Window({title:"my window", width:400, draggable : false, shadow : false, resizable : false, shim :false, autoDestroy : true, height:300});
关闭这个window时 产生很多ie无法自动回收的孤立结点
每次创建 关闭 创建 关闭 ....
孤立结点都会越来越多
也许这是IE的错 但是EXT不应该忽视IE的 毕竟IE的占有率在那里放着呢
还请大家帮忙分析分析
我看了一下 window/panel的destroy方法似乎确实存在着一些缺陷啊
我重写了 window的destroy方法,效果提升一些,一些顽固结点可以删除了
但是还剩下一下更加顽固的结点无法删除
Ext.Window.prototype.beforeDestroy = function(){ Ext.Window.superclass.beforeDestroy.call(this); Ext.destroy( this.header, this.tbar, this.bbar, this.footer, this.body, this.bwrap, this.focusEl, this.toolTarget, this.resizer, this.dd, this.proxy, this.mask ); this.header=null; this.tbar=null; this.bbar=null; this.footer=null; this.body=null; this.bwrap=null; this.focusEl=null; this.toolTarget=null; this.resizer=null; this.dd=null; this.proxy=null; this.mask=null; }
这个问题如果不弄明白, 在一个复杂的ext页面内,随着操作的增加 内存消耗也将越来越大.
deskto那个例子里的 窗口 大家打开关闭打开关闭 几个来回之后内存占用就会达到6 7十M了.
我怀疑 ext的各个组件的destroy方法内部的实现考虑的不够全面, 销毁内容 和销毁顺序 不当造成部分元素无法销毁.
希望大家能够一起讨论分析一下ext的问题到底处在哪里
评论
16 楼
gdipkf1986
2008-03-19
呵呵,等着楼主的解决方法.自己目前还没有这个能力去做这个事情.
15 楼
fins
2008-03-19
找到解决办法了 一会发新帖
=======================
收回上面的话 虽然可以解决 但是会打乱ext的依赖 再想想先
=======================
收回上面的话 虽然可以解决 但是会打乱ext的依赖 再想想先
14 楼
znjq
2008-03-19
我的意思是为了证明问题原因注释掉测试一下。
还是等ext自己去解决,或者自己小心使用了。呵呵
还是等ext自己去解决,或者自己小心使用了。呵呵
13 楼
nihongye
2008-03-18
引用
觉的还是这2行的问题
Java代码 复制代码
1. fn._handlers = fn._handlers || [];
2. fn._handlers.push([Ext.id(el), ename, h]);
fn._handlers = fn._handlers || [];
fn._handlers.push([Ext.id(el), ename, h]);
这里的_handlers只在Eventmanager里面stopListening的时候做判断才用到,别的地方没看到过。感觉这里设计的有点多余,别的地方removeListener的时候又没有处理这块. 可能eventmanager和ext-base是不同人写的,呵呵。
你把这2行注释掉,就不会出现上面的内存问题了
Java代码 复制代码
1. fn._handlers = fn._handlers || [];
2. fn._handlers.push([Ext.id(el), ename, h]);
fn._handlers = fn._handlers || [];
fn._handlers.push([Ext.id(el), ename, h]);
这里的_handlers只在Eventmanager里面stopListening的时候做判断才用到,别的地方没看到过。感觉这里设计的有点多余,别的地方removeListener的时候又没有处理这块. 可能eventmanager和ext-base是不同人写的,呵呵。
你把这2行注释掉,就不会出现上面的内存问题了
注释掉恐怕不行,因为实际有些地方使用了el.un(...,fn)的方式停止监听,在ext的论坛上搜索_handlers destory,可以找到一篇11份的帖子提到这个问题,ext的开发人员在一些相关的回答中隐约说了要解决这个问题。假如ext本身保证了以非global function作为监听器,或者我们小心点去避免这个问题,呵呵。
12 楼
znjq
2008-03-18
觉的还是这2行的问题
这里的_handlers只在Eventmanager里面stopListening的时候做判断才用到,别的地方没看到过。感觉这里设计的有点多余,别的地方removeListener的时候又没有处理这块. 可能eventmanager和ext-base是不同人写的,呵呵。
你把这2行注释掉,就不会出现上面的内存问题了
fn._handlers = fn._handlers || []; fn._handlers.push([Ext.id(el), ename, h]);
这里的_handlers只在Eventmanager里面stopListening的时候做判断才用到,别的地方没看到过。感觉这里设计的有点多余,别的地方removeListener的时候又没有处理这块. 可能eventmanager和ext-base是不同人写的,呵呵。
你把这2行注释掉,就不会出现上面的内存问题了
11 楼
fins
2008-03-18
我刚才看了一下 purgeElement 方法到最后还是调用了 stopLisener吧
=====================
(又仔细看了一下 没掉 呵呵 un方法调用了 但是destroy里的那个 removeAllLisener没有调 呵呵 我看错了 )
我觉得问题的关键是 ext的一个地方设计的有问题
他应该先 wrap 后备份
也就是说 ext-base.js 第240行的
这个操作应该早做 不应该在这一部里做
应该在 eventmanage.js 里的 addListener(205行)里做
先wrap 之后完全操作的是这个wrap之后的function
=====================
(又仔细看了一下 没掉 呵呵 un方法调用了 但是destroy里的那个 removeAllLisener没有调 呵呵 我看错了 )
我觉得问题的关键是 ext的一个地方设计的有问题
他应该先 wrap 后备份
也就是说 ext-base.js 第240行的
var wrappedFn = function(e) { return typeof Ext != 'undefined' ? fn(Ext.lib.Event.getEvent(e)) : false; };
这个操作应该早做 不应该在这一部里做
应该在 eventmanage.js 里的 addListener(205行)里做
先wrap 之后完全操作的是这个wrap之后的function
10 楼
fins
2008-03-18
谢谢2位 你们提供的线索很重要啊 呵呵
我打算想办法改写一下ext的这个问题
到时候有不明白的还要请教2位 谢谢了先
另外最近我的一个工作就是优化ext (减少EXT对内存和cpu资源的占用)
由于之前并不是很了解ext的架构 所以想听听大家的建议
希望有同好者可以和我一起研究 谢谢了
我打算想办法改写一下ext的这个问题
到时候有不明白的还要请教2位 谢谢了先
另外最近我的一个工作就是优化ext (减少EXT对内存和cpu资源的占用)
由于之前并不是很了解ext的架构 所以想听听大家的建议
希望有同好者可以和我一起研究 谢谢了
9 楼
znjq
2008-03-18
nihongye 的分析是正确的。
on的加入是通过EventManager的addListener方法来做的,这里在每个fn上绑定了_handlers,purgeElement的时候通过Ext.lib.Event的removeListener方法,
见300行
但是这里是只是删除了fn,没有清楚掉里面的handlers,而handlers有el的引用,因为没法清楚对象.而这个时候fn也就是alertMsg是在window下的,我测了一下,单纯删除他是没用的,必须wrap一下,所以出现了你说的必须用function(){
alertMsg()
}
才正确的情况
on的加入是通过EventManager的addListener方法来做的,这里在每个fn上绑定了_handlers,purgeElement的时候通过Ext.lib.Event的removeListener方法,
见300行
delete listeners[index][this.WFN]; delete listeners[index][this.FN];
但是这里是只是删除了fn,没有清楚掉里面的handlers,而handlers有el的引用,因为没法清楚对象.而这个时候fn也就是alertMsg是在window下的,我测了一下,单纯删除他是没用的,必须wrap一下,所以出现了你说的必须用function(){
alertMsg()
}
才正确的情况
8 楼
nihongye
2008-03-18
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="/script/yuiExt/resources/css/ext-all.css" /> <script type="text/javascript" src="/script/yuiExt/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="/script/yuiExt/ext-all.js"></script> <script type="text/javascript"> function alertMsg(){ alert('click div c'); } function addEventDiv(){ if (!Ext.get("div1") ){ return; } // 使用下面这种方式注册事件 , 那么ext无法正确的移除 Ext.get("div1").on("click",alertMsg); } Ext.onReady(function(){ Ext.get("btn1").on("click",addEventDiv); Ext.get("btn2").on("click",function(){ Ext.destroy(Ext.get("div1")); alert(alertMsg._handlers.length); alert(alertMsg._handlers[0][0]); alert(alertMsg._handlers[0][1]); alert(alertMsg._handlers[0][2]); }); }); </script> </head> <body > <input id="btn1" type="button" value=" 为 div1 添加事件 " /> <input id="btn2" type="button" value=" 移除 div1 " /> <div id="div1">I'm div 1</div> </body> </html>
发现问题在于ext的 wrap function,就是listener是global的话就会有问题。
见 EventManager.js的140行:
fn._handlers = fn._handlers || []; fn._handlers.push([Ext.id(el), ename, h]);
这里给传入的listener加了_handlers属性,stopLisener负责清除,那么就能正确的处理。
但是destroy直接调用了E.purgeElement...,这个方法好像没办法看到原来的listen,所以,没办法正确的清除_handlers,而_handlers引用了element
7 楼
nihongye
2008-03-18
但其实ext已经用传入的function包装了一个新的function,然后才绑定到节点去。
6 楼
fins
2008-03-18
en 代码上确实没找到什么问题
但是实际情况就是无法移除
而如果用下面的方法给上面代码中的 div注册事件 那么就可以移除:
但是实际情况就是无法移除
而如果用下面的方法给上面代码中的 div注册事件 那么就可以移除:
Ext.get("div1").on("click",function(){ alertMsg() });
5 楼
nihongye
2008-03-18
前几天也研究过这里的代码,看不出漏洞在那,lisenter的移除,节点的移除都是正确的。。。
4 楼
fins
2008-03-18
下面这段代码也有问题
看来 ext的 Ext.destroy 果然不够强大
问题还是出在事件管理方面
疑惑中
看来 ext的 Ext.destroy 果然不够强大
问题还是出在事件管理方面
疑惑中
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="../resources/css/ext-all.css" /> <script type="text/javascript" src="../adapter/ext/ext-base.js"></script> <script type="text/javascript" src="../ext-all.js"></script> <script type="text/javascript"> function alertMsg(){ alert('click div c'); } function addEventDiv(){ if (!Ext.get("div1") ){ return; } // 使用下面这种方式注册事件 , 那么ext无法正确的移除 Ext.get("div1").on("click",alertMsg); } Ext.onReady(function(){ Ext.get("btn1").on("click",addEventDiv); Ext.get("btn2").on("click",function(){ Ext.destroy(Ext.get("div1")); }); }); </script> </head> <body > <input id="btn1" type="button" value=" 为 div1 添加事件 " /> <input id="btn2" type="button" value=" 移除 div1 " /> <div id="div1">I'm div 1</div> </body> </html>
3 楼
fins
2008-03-18
问题的根本原因找到了
一会儿单独发帖讨论
一会儿单独发帖讨论
2 楼
nihongye
2008-03-18
ext1.1 里启用垃圾回收后,等30秒才从Element的cache里清除。
刷新页面后内存还占用?
刷新页面后内存还占用?
1 楼
fins
2008-03-18
jack要让我疯狂了!!!!
为了找出问题所在 我一行行的分析 2.02版本代码的 太辛苦了
看到一个地方彻底崩溃了
Template.js 204行
return returnEl ? Ext.get(newNode, true) : newNode;
注意 Ext.get(newNode, true)
再来看 Ext.get 方法的代码
Element.js 2880行
我是绞尽脑汁也没弄明白那个true是做什么的
我怀疑这个地方jack弄错了
他本意可能是要给 get弄一个是否从cache里取对象的参数吧
但是没有写.
为了找出问题所在 我一行行的分析 2.02版本代码的 太辛苦了
看到一个地方彻底崩溃了
Template.js 204行
return returnEl ? Ext.get(newNode, true) : newNode;
注意 Ext.get(newNode, true)
再来看 Ext.get 方法的代码
Element.js 2880行
El.get = function(el){ var ex, elm, id; if(!el){ return null; } if(typeof el == "string"){ // element id if(!(elm = document.getElementById(el))){ return null; } if(ex = El.cache[el]){ ex.dom = elm; }else{ ex = El.cache[el] = new El(elm); } return ex; }else if(el.tagName){ // dom element if(!(id = el.id)){ id = Ext.id(el); } if(ex = El.cache[id]){ ex.dom = el; }else{ ex = El.cache[id] = new El(el); } return ex; }else if(el instanceof El){ if(el != docEl){ el.dom = document.getElementById(el.id) || el.dom; // refresh dom element in case no longer valid, // catch case where it hasn't been appended El.cache[el.id] = el; // in case it was created directly with Element(), let's cache it } return el; }else if(el.isComposite){ return el; }else if(Ext.isArray(el)){ return El.select(el); }else if(el == document){ // create a bogus element object representing the document object if(!docEl){ var f = function(){}; f.prototype = El.prototype; docEl = new f(); docEl.dom = document; } return docEl; } return null; }; // 省去一些..... Ext.get = El.get;
我是绞尽脑汁也没弄明白那个true是做什么的
我怀疑这个地方jack弄错了
他本意可能是要给 get弄一个是否从cache里取对象的参数吧
但是没有写.
发表评论
-
HTML5 与 ”性工能“障碍
2012-12-13 18:08 9539HTML5 与 ”性工能“障碍 最近看了@王淮Harr ... -
聊聊 iOS 5 和 iOS 6 在HTML5 canvas渲染上的差异
2012-09-13 18:40 5958我录制了一段iphone4s 下 ios 5 和 ios 6 ... -
尝试挑战 running panda , HTML5的跑酷类游戏(开发中)
2011-08-01 00:02 5998我业余时间一直在尝试用HTML5 在ios平台上开发webga ... -
移动互联网 与 Web标准化技术
2011-07-14 19:54 3667移动互联网 与 Web标准化技术 ... -
为什么我喜欢safari 胜过chrome和ff?
2011-07-04 00:35 7796抛下IE不谈,目前在浏览器市场里 最受欢迎的莫过于chrome ... -
欢迎参加 "移动平台HTML5动画性能大赛"
2011-03-31 11:38 3776移动平台HTML5动画性能大赛 注 : 此页面为临时页面 待 ... -
为什么在今天,我要选择HTML5 (上) 【此文标题党,还是别看了】
2011-03-30 16:19 4007当初苹果禁止Flash登陆iOS设备时,曾经引起过一场“HTM ... -
HTML5游戏开发入门实例<脆弱的马里奥>
2011-03-14 20:10 10137HTML5游戏开发入门实例<脆弱的马里奥>: ht ... -
3月26号,北京,我将做一期HTML5游戏开发的技术讲座,欢迎参加.
2011-03-11 11:57 21433月26号,我将去北京做一次"html5游戏开发入门 ... -
w3ctech 2011 - 拥抱HTML5 技术大会即将召开,欢迎报名
2011-03-03 23:46 1636w3ctech 2011 - 拥抱HTML5 技术会议将于4月 ... -
[新增视频]我在<当HTML5来敲门>技术沙龙上做的一个关于HTML5游戏开发的分享
2011-02-27 11:03 1925我在2月26号的<当HTML5来敲门>技术沙龙上做 ... -
说说 iOS safari在retina屏下显示图像的原理
2011-02-24 17:05 8215我在 简析 HTML5 canvas在retina屏(视网膜屏 ... -
一个 HTML5 编写的 简谱播放程序
2011-02-17 15:14 3836一个 HTML5 编写的 简谱播放程序 : http:// ... -
试用了一下 HP touchPad ,有点小失望.
2011-02-16 12:57 2813我手里的这台机器是 工程样机. 从样机来看, 这台平板并不出色 ... -
简析 HTML5 canvas在retina屏(视网膜屏幕,如iphone4)设备上的优化(更新原理)
2011-02-11 04:01 9578随着iphone4 的推出, retina ... -
[更新,bug修复了]chrome开启canvas 2D GPU加速后, clearRect的一个严重bug.
2011-01-24 15:54 9818最新版的 chromium. 已经修复了这个bug 经过进一 ... -
我也来重复造个轮子吧 ,发布一个利用原型,在Javascript中实现类机制的简单框架: GT-Class
2011-01-07 11:23 3449我也来重复造个轮子吧 ,发布一个利用prototype(原型, ... -
关于"GPU加速"的简单问答.
2011-01-05 22:34 2744如今使用GPU来代替CPU进 ... -
求助:用这样的方式写Kissy组件,可行吗?(Kissy推荐的方式是怎样的?)
2010-12-29 09:43 2033看了Kissy自带组件的代码,又看了你在D2上的PPT , 看 ... -
简单聊一聊百度的开源JS库:Tangram
2010-12-24 12:20 9505简单聊一聊百度的开源JS库:Tangram 最近百度开源了 ...
相关推荐
在上述的魔法特效脚本中,`Start()`方法里就使用了`Destroy(gameObject, destroyTime)`来设置对象在一定时间后自动销毁。 3. **碰撞检测与刚体(Rigidbody)**: 如果你需要在游戏对象被销毁前检测碰撞,你需要为...
### JAVA项目实践:URL存在的跨站漏洞与注入漏洞解决方案 #### 一、跨网站脚本(XSS)概述 跨网站脚本(Cross-site scripting,通常简称为XSS或跨站脚本攻击)是一种常见的安全漏洞攻击方式,尤其针对网站应用程序。...
标题“destroy”所指的可能是一款名为“桌面破坏”(Desktop Destroy)的软件,它作为一个发泄工具,让用户可以通过虚拟的方式“砸桌面”,从而在电脑上体验一种减压的乐趣。这款软件的设计理念是为了提供一种轻松的...
EXT核心API详解 1、Ext类 ………………………………… 2 2、Array类 …………………………… 4 3、Number类 …………………………… 4 4、String类 …………………………… 4 5、Date类 ……………………………… 5 ...
- **配置项**:包括`modal`(是否为模态窗口)、`draggable`(是否可拖动)、`resizable`(是否可调整大小)、`closeAction`(关闭窗口时的行为,如`destroy`或`hide`)等。 - **方法**:`show`用于显示窗口,`...
5. `destroy`: 这是一个通用销毁方法,可以尝试移除传入的DOM元素、事件监听器,并调用它们的`destroy`方法(如果存在)。它有助于清理资源,防止内存泄漏。 6. `each`: 用于遍历数组或NodeList,并对每个元素执行...
它包含了许多配置项,如id、xtype、style等,以及方法如show、hide、destroy等,用于控制组件的显示、隐藏和销毁。 在EXT中文API中,开发者可以找到关于EXT Grid、EXT Form、EXT Window、EXT Chart等关键组件的详细...
- 组件销毁:确保正确调用`destroy`方法来销毁EXT组件。这将清理组件及其关联的DOM元素和资源。 - DOM元素处理:在组件销毁时,除了调用`destroy`,还需要检查并手动清理可能存在的DOM元素引用。 2. 使用内存...
items)`: 这个方法用于销毁一个或多个`Ext.Element`或`Ext.Component`,清理它们的事件监听器,删除DOM节点,并调用对象的`destroy`方法(如果存在)。 这些是Ext.js中的一些核心函数,它们在开发复杂的交互式Web...
之前写了一个activity加载fragment的比较low,那个是放在xml布局里面动态控制show和hide实现的,这个代码也是通过show和hide实现显示和隐藏防止destroy,但是可以动态加载fragment实例,不用再把fragment放在xml布局...
这里通过`Ext.getCmp('activeTest')`找到指定ID的面板,并通过`.show()`方法使其可见,再使用`unhideTabStripItem`方法恢复标签栏中的显示。 #### 总结 通过以上两种方法——调整`autoDestroy`和`closeAction`属性...
此方法尝试销毁传入的每个对象,包括移除 DOM 节点、事件监听器,并调用它们的 `destroy` 方法(如果存在)。 **示例代码:** ```javascript var element = document.getElementById('some-element'); destroy...
当访问一个 Servlet 时,...C 判断指定名字的 HTTP 文件头是否存在 D 向客户端发送错误信息 pageContext 对象的 findAttribute() 方法的作用是 A.用来设置默认页面的范围或指定范围之中的已命名对象 B.用来删除默