2011-07-27 4 views
4

ここで説明するにはアプリケーションが大きすぎますが、クライアントがいつでも使用できるモジュールが20個以上あることがわかります。そして、画面の後に画面を読み込むと、私のアプリケーションは500MB以上のオーキュートになります。Flex ModuleLoaderコンポーネントがメモリリークを引き起こします。モジュールを正しくアンロードするにはどうしたらいいですか?

私はモジュールをロードし、アンロードするために使用するスクリプトは次のとおりです。

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オブジェクトとchildオブジェクトを削除します。どうやって私の記憶は元のままになっていて、新しいモジュールを開いたときにその上にさらに多くのメモリがロードされますか?ああ!

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; 
     } 
    } 
+1

各モジュールの子コンポーネントも 'eventListeners'を削除していることを確認してください。私はこれらのモジュールのどれも 'HierarchicalData'で' AdvancedDataGrids'を持っているとは思わないでしょうか? –

+0

はい、それらはすべて高度なデータグリッドを持っています。いくつかのモジュールにもポップアップが漏れていますが、別のモジュールをナビゲートするときにデータを漏らすためにアプリケーションを開く必要はありません。 – overmann

+1

これらのAdvancedDataGridは 'HierarchicalData'を使用していますか?私は私の 'AdvancedDataGrids'がメモリリークを引き起こしていた同様の問題に遭遇しました。 –

答えて

1

this articleより:

AdvancedDataGridHierachicalDataを使用して、制御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 = {}; 
} 
+0

これは恥ずかしそうに聞こえるでしょうが、そのイベントリスナーをCollectionEventクラスに追加する場所がわかりません。または私は完全に失われていますか? – overmann

+0

@overmann心配はいりません。 :)簡単な例は、http://kb2.adobe.com/cps/897/cpsid_89785.htmlを参照してください。 –

+0

待ちます。ここに問題があります。私のdg.dataProviderオブジェクトはIHierarchicalCollectionViewとして認識されません。 – overmann

2

Flex 4.5を使用している場合は、<s:ModuleLoader/>を代わりに使用してください。 詳細:here

+0

私はFlex 4を使用していますが、現在はswtichには遅すぎ、proyectは行っており、すでにクライアントが使用しています。私は現在、を使用しています。 – overmann

関連する問題