`
nihongye
  • 浏览: 101152 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

ExtJs内存泄漏----组件泄漏检查

阅读更多
在单页式的Extjs应用中,由于Extjs存在许多的全局变量,这些全局变量包括了如:
Element Cache,Event Cache,ComponentMgr,ButtonMgr等等,内存的泄漏往往由于组件销毁时,没注意清除这些变量而引起。在2.2由guig提供的patch包,很大程度上保证了Extjs自带的组件正确的销毁。
下面提供一个检测ComponentMgr中是否累积了Component的代码:
function() {
                var items = Ext.ComponentMgr.all.items;
                var comIds = ewp.util.CheckLeakInEvents.comIds = ewp.util.CheckLeakInEvents.comIds || {};
                //累加组件出现次数
                for (var i = 0; i < items.length; i++)
                {
                    comIds[items[i].id] = (comIds[items[i].id] || 0) + 1;
                }
                //打印出现次数超过一次的组件Id
                var result = [];
                for(var key in comIds)
                {
                    if(comIds[key] > 1)
                    {
                        result.push(key + "=" + comIds[key]);
                    }
                }
                alert(result.join(", "));
            }

该方法可以作为一个Button的handler,每次点击一次,察看那些组件累积在了ComponentMgr中,结合FireBug设置断点,通过Ext.ComponentMgr(id),察看更多的组件信息。
遇到组件泄漏的场景:
如 tbar = [new TextField({...})],tbar所在的Grid作为TabItem,并且该TabItem延迟渲染,那么由于new TextField({...})已经注册,但因为未渲染,toolbar中未添加该Field为其Item,导致未销毁组件。(解决办法:通过复写onDestroy主动销毁,或是使用{xtype:""}延迟组件创建),总之,如果主动new ...的组件,那么注意销毁时,是否销毁了相应的组件。
分享到:
评论
4 楼 nihongye 2009-05-30  
刚好最近一个朋友问起,重新整理出来几个方法,如下:

//用于解决内存问题,检查Ext状态的几个方法:
//统计新增组件
function countAddComs() {
    var items = Ext.ComponentMgr.all.items;
    var comIds = window.extComIds = window.extComIds || {};
    for (var i = 0; i < items.length; i++)
    {
        comIds[items[i].id] = (comIds[items[i].id] || 0) + 1;
    }
    var result = [];
    var adds = [];
    for (var key in comIds)
    {
        if (comIds[key] >= 1)
        {
            result.push(key + "=" + comIds[key]);
            if (comIds[key] == 1) {
                //显示新增的组件
                //console.log(Ext.getCmp(key)) //firefox+firebug下可用这句查看组件详细的信息
                adds.push(Ext.getCmp(key).ctype + " " + Ext.getCmp(key).getXType() + " " + Ext.getCmp(key).text)
            }
        }
    }
    alert(adds.join(","));
    alert(result.join(", "));
}






//统计各全局组件管理器数量
function count() {
    var result = [];
    var count = 0;
    var x = Ext.menu.MenuMgr.menus;
    if (x) {
        for (var key in x)
        {
            count++;
        }
        result.push("menus = " + count);
    }

    count = 0;
    x = Ext.dd.ScrollManager.els;
    if (x) {
        for (var key in x)
        {
            count++;
        }
        result.push("scrolls = " + count);
    }
    count = 0;
    x = Ext.dd.DragDropMgr.ids;
    if (x) {
        var keys = "";
        for (var key in x)
        {
            count++;
        }
        result.push("dragdrop = " + count + " " + keys);

    }
    x = Ext.ButtonToggleMgr.groups;
    if (x) {
        for (var key in x)
        {
            count++;
        }
        result.push("butontoggle = " + count);
    }
    result.push("comp = " + Ext.ComponentMgr.all.length)
    result.push("store = " + Ext.StoreMgr.length)
    if (Ext.util.TaskRunner.tasks)
    {
        result.push("tasks = " + Ext.util.TaskRunner.tasks.length)
    }
    alert(result.join("\n"));
}






//统计Elements和事件数量
function countElmentsAndEvents() {
    //统计
    var elementCacheCouunt = 0;
    for (var key in Ext.Element.cache)
    {
        elementCacheCouunt++;
    }
    var _flyweightsCount = 0;
    for (var key in Ext.Element._flyweights)
    {
        _flyweightsCount++;
    }
    var eventCount = 0;
    var enames = {};
    for (var key in Ext.EventManager.elHash)
    {
        eventCount++;
        var es = Ext.EventManager.elHash[key]
        if (es) {
            for (var ename in es) {
                if (es.hasOwnProperty(ename)) {
                    enames[ename] = (enames[ename] || 0) + 1
                }
            }
        }
    }
    //显示各个全局变量的数量
    alert("elementCacheCouunt = " + elementCacheCouunt + ", _flyweightsCount = " + _flyweightsCount + ",eventCount = " + eventCount)
    //比较事件的增长
    var result = [];
    window.extEventNames = window.extEventNames || {};
    for (var key in enames)
    {
        window.extEventNames[key] = window.extEventNames[key] || 0;
        var added = enames[key] - window.extEventNames[key];
        if (added > 0)
        {
            result.push(key + ":total = " + enames[key] + ",add =" + added);
        }
    }
                //显示增长的事件及数量
    alert(result.join(","))
                //记录本次统计的事件名,留做与新的事件做比较
    window.extEventNames = enames;
}


在解决HtmlEditor的内存问题时,分别使用了:
1.通过使用"统计Elements和事件数量"检查出组件没有移除掉doc上的鼠标和键盘事件
2.通过使用"统计新增组件"检查出来ColorItem没有销毁掉ColorPalette组件
3 楼 dzxiang 2009-05-30  
“ewp.util.CheckLeakInEvents”
能否共享一下?
2 楼 willer 2009-03-04  
               
1 楼 会飞的狗 2009-02-06  
用了那个patch包,比以前是强了点。但是每刷新一次页面,还是有内存泄露。

相关推荐

Global site tag (gtag.js) - Google Analytics