Flex ModuleLoader组件导致内存泄漏。如何正确卸载模块?

时间:2011-07-27 22:52:54

标签: flex memory-leaks flex3 flex4

应用程序太大了,无法在此描述,但我可以告诉您,我有多达20个模块或更多客户端可以随时使用。如果我继续在屏幕后加载屏幕,我的应用程序可能会超过500MB甚至更多。

我用来加载和卸载模块的脚本是:

public function createModule(modulo:String):void {
                if(moduleLoader != null){
                    moduleLoader.unloadModule();
                    //moduleLoader.url = null;
                    moduleLoader.url = "com/oss/facturable/components/" + modulo + "?version=" + model.configXML.versionApp;    
                    moduleLoader.loadModule();
                }       
            }
            private function errorHandler(e:ModuleEvent):void {
                Alert.show("No se ha podido cargar el modulo. Contacte al departamento técnico.");
            }

加载模块的Container:

<s:BorderContainer width="98%" height="98%" includeIn="mainState" styleName="bcModuleLoader" top="100">
                    <s:layout>
                        <s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10"/>
                    </s:layout>
                    <s:Scroller width="100%" height="100%">
                        <s:Group>
                            <mx:ModuleLoader id="moduleLoader" error="errorHandler(event)" width="100%" height="100%" horizontalAlign="center" verticalAlign="top" creationComplete="createModule('bandejaEntrada.swf')"/>              
                        </s:Group>
                    </s:Scroller>
 </s:BorderContainer>

每当我点击我认为与此处发布无关的菜单选项时,都会调用createModule函数。总而言之,这就是我现在所做的一切,使其发挥作用和泄漏:S

这是官方的unloadModule函数,我想,从它的外观来看,内存应该很好地分配这个东西,我的意思是,看!它删除所有eventListeners和子对象。为什么我的内存在卸载时保持不变,并在打开新模块时在其上加载更多内存?! Augh!

public function unloadModule():void
    {
        if (child)
        {
            removeChild(child);
            child = null;
        }

        if (module)
        {
            module.removeEventListener(ModuleEvent.PROGRESS,
                                       moduleProgressHandler);
            module.removeEventListener(ModuleEvent.SETUP, moduleSetupHandler);
            module.removeEventListener(ModuleEvent.READY, moduleReadyHandler);
            module.removeEventListener(ModuleEvent.ERROR, moduleErrorHandler);

            module.unload();
            module.removeEventListener(ModuleEvent.UNLOAD, moduleUnloadHandler);
            module = null;
        }
    }

2 个答案:

答案 0 :(得分:2)

如果您使用的是Flex 4.5,请尝试使用<s:ModuleLoader/>。 更多详情:here

答案 1 :(得分:1)

来自this article

HierachicalDataAdvancedDataGrid一起使用时,控件会使用IHierarchicalCollectionView界面跟踪分层数据和分组数据。该接口具有openNodes属性,该属性包含一组对象,这些对象表示当前在AdvancedDataGrid中打开的数据提供程序的节点。

如果使用新数据提供程序替换数据提供程序,则AdvancedDataGrid控件不会清除openNodes属性。由于openNodes属性包含对旧数据提供程序中对象的引用,因此无法通过垃圾回收从内存中删除对象。要确保可以从内存中删除旧数据提供程序,请在替换数据提供程序时使用事件处理程序清除openNodes属性。

向数据提供者的CollectionEvent.COLLECTION_CHANGE事件添加事件侦听器以清除openNodes属性。

// Handle the colectionChange event.
private function removeOpenNodes(event:CollectionEvent):void 
{
  if(event.kind == CollectionEventKind.RESET)
    IHierarchicalCollectionView(adg.dataProvider).openNodes = {};
}