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

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

Решение

Из этой статьи:

Когда используешь 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 = {};
}

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

Другие вопросы по тегам