Компонент Flex ModuleLoader, вызывающий утечку памяти.Как правильно выгрузить модули? - PullRequest
4 голосов
/ 28 июля 2011

Приложение слишком велико, чтобы описывать его здесь, но я могу сказать, что у меня есть до 20 или более модулей, которые клиент может использовать в любое время.И если я продолжаю загружать экран за экраном, мое приложение может занимать 500 МБ и более.

Сценарий, который я использую для загрузки и выгрузки модулей:

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.");
            }

Контейнер, в котором находитсязагружен модуль:

<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 и дочерние объекты.Почему моя память остается неизменной при выгрузке и загружает больше памяти, когда я открываю новый модуль ?!Ауг!

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 ]

2 голосов
/ 01 августа 2011

Если вы используете Flex 4.5, попробуйте вместо него использовать <s:ModuleLoader/>. Подробнее: здесь

1 голос
/ 01 августа 2011

С этой статьи :

При использовании HierachicalData с AdvancedDataGrid элемент управления отслеживает иерархические и сгруппированные данные с помощью интерфейса 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 = {};
}
...