11 Replies Latest reply on Oct 7, 2014 7:47 PM by Jeff ZM Li

    Datagrid column in module causing memory leak

    JamesEco

      Hi All

       

      I'm having trouble with a DataGrid column preventing a module from being release properly. I can't imagine this is the intended behaviour.

       

      Using this simple test case, a WindowedApplication and an mx:Module I wonder if anyone else can reproduce this problem. The issue goes away if you simply comment out the GridColumn Instance.

       

      Can anyone offer any advice?

       

      Many thanks

       

      James

       

       

      DataGridTest.mxml

      <?xml version="1.0" encoding="utf-8"?>
      <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                             xmlns:s="library://ns.adobe.com/flex/spark" 
                             xmlns:mx="library://ns.adobe.com/flex/mx">
          <fx:Script>
              <![CDATA[
                  import mx.core.IVisualElement;
                  import mx.events.ModuleEvent;
                  import mx.modules.IModuleInfo;
                  import mx.modules.ModuleManager;
      
                  private var assetModule:IModuleInfo;
                  protected function load_clickHandler(event:MouseEvent):void
                  {
                      assetModule = ModuleManager.getModule('DataGridTestModule.swf');
                      assetModule.addEventListener("ready", getModuleInstance);
                      assetModule.load();
                  }
                  public function getModuleInstance(event:ModuleEvent):void 
                  {
                      var sm:DisplayObject = assetModule.factory.create() as DisplayObject;
                      sm.addEventListener("close", closeModule);
                      contentHolder.addElement(sm as IVisualElement);
                  }
                  private function closeModule(event:Event):void 
                  {
                      event.target.removeEventListener("close", closeModule);
                      contentHolder.removeElement(event.target as IVisualElement);
                      assetModule.unload();
                      assetModule = null;
                  }
              ]]>
          </fx:Script>
          <s:VGroup width="100%" height="100%">
              <s:HGroup >
                  <s:Button id="load" label="Load" click="load_clickHandler(event)"/>
              </s:HGroup>
              <s:BorderContainer id="contentHolder" width="100%" height="100%"/>
          </s:VGroup>
      </s:WindowedApplication>
      

       

      DataGridTestModule.mxml

       

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Module xmlns:fx="http://ns.adobe.com/mxml/2009" 
                            xmlns:s="library://ns.adobe.com/flex/spark" 
                            xmlns:mx="library://ns.adobe.com/flex/mx" 
                            layout="absolute" xmlns:components="components.*">
          <fx:Script>
              <![CDATA[
                  protected function close_clickHandler(event:MouseEvent):void
                  {
                      dispatchEvent(new Event('close', true, false))
                  }
              ]]>
          </fx:Script>
          <s:BorderContainer id="contacts"
                             width="100%" height="100%"
                             backgroundAlpha="0"
                             borderVisible="false">
              <s:layout>
                  <s:VerticalLayout/>
              </s:layout>
              <s:Button id="close" label="Close" click="close_clickHandler(event)"/> 
              <s:DataGrid id="queries" >
                  <s:columns>
                      <s:ArrayList>
                          <s:GridColumn/> <!-- Comment out this GridColumn instance to see the leak disappear -->
                      </s:ArrayList>
                  </s:columns>
              </s:DataGrid>
          </s:BorderContainer>
      </mx:Module>
      
        • 1. Re: Datagrid column in module causing memory leak
          Flex harUI Adobe Employee

          Another test is to link GridColumn into the main app and see if that allows the module to unload.  Then we’ll have to look at what GridColumn pulls in.

          • 2. Re: Datagrid column in module causing memory leak
            JamesEco Level 1

            Thanks for your reply. Sorry if I'm being dense, but I don't understand what you mean by "link GridColumn into the main app"?

             

            Kind regards

             

            James

            • 3. Re: Datagrid column in module causing memory leak
              JamesEco Level 1

              OK, So I've done some more testing. Creating the GridColumn in AS during the creationComplete event is a slight improvement. It seems to allow the DataGrid and the Module be GC'd, but it's still leaking memory somewhere. I just can't get my head around the Profiler. Also, it's going to be a massive headache if we have to rewrite our application to create all the GridColumns in AS. Surely this shouldn't be necessary?

               

              New test case below:

               

              DataGridTest.mxml

               

              <?xml version="1.0" encoding="utf-8"?>
              <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                                     xmlns:s="library://ns.adobe.com/flex/spark" 
                                     xmlns:mx="library://ns.adobe.com/flex/mx">
                  <fx:Script>
                      <![CDATA[
                          import mx.collections.ArrayList;
                          import mx.core.IVisualElement;
                          import mx.events.ModuleEvent;
                          import mx.modules.IModuleInfo;
                          import mx.modules.ModuleManager;
                          
                          import spark.components.gridClasses.GridColumn;
                          
                          private var assetModule:IModuleInfo;
                          private var sm:DisplayObject;
                          protected function load_clickHandler(event:MouseEvent):void
                          {
                              assetModule = ModuleManager.getModule('DataGridTestModule.swf');
                              assetModule.addEventListener("ready", getModuleInstance);
                              assetModule.load();
                          }
                          public function getModuleInstance(event:ModuleEvent):void 
                          {
                              sm = assetModule.factory.create() as DisplayObject;
                              sm.addEventListener("close", closeModule);
                              contentHolder.addElement(sm as IVisualElement);
                          }
                          private function closeModule(event:Event):void 
                          {
                              event.target.removeEventListener("close", closeModule);
                              contentHolder.removeElement(event.target as IVisualElement);
                              assetModule.unload();
                              assetModule = null;
                          }
                      ]]>
                  </fx:Script>
                  <s:VGroup width="100%" height="100%">
                      <s:HGroup >
                          <s:Button id="load" label="Load" click="load_clickHandler(event)"/>
                      </s:HGroup>
                      <s:BorderContainer id="contentHolder" width="100%" height="100%"/>
                  </s:VGroup>
              </s:WindowedApplication>
              

               

              DataGridTestModule.mxml

               

              <?xml version="1.0" encoding="utf-8"?>
              <mx:Module xmlns:fx="http://ns.adobe.com/mxml/2009" 
                                    xmlns:s="library://ns.adobe.com/flex/spark" 
                                    xmlns:mx="library://ns.adobe.com/flex/mx" 
                                    creationComplete="module1_creationCompleteHandler(event)"
                                    layout="absolute" xmlns:components="components.*">
                  <fx:Script>
                      <![CDATA[
                          import flash.utils.setTimeout;
                          
                          import mx.collections.ArrayList;
                          import mx.events.FlexEvent;
                          
                          import spark.components.gridClasses.GridColumn;
                           [Bindable]
                          private var _col:ArrayList = new ArrayList(); 
                          protected function close_clickHandler(event:MouseEvent):void
                          {
                              
                              dispatchEvent(new Event('close', true, false))
                          }
                          protected function module1_creationCompleteHandler(event:FlexEvent):void
                          {
                              var gc:GridColumn = new GridColumn();
                              gc.headerText = 'Test Column';
                              _col.addItem(gc);
                          }
                          
                      ]]>
                  </fx:Script>
                  <s:BorderContainer width="100%" height="100%">
                      <s:layout>
                          <s:VerticalLayout/>
                      </s:layout>
                      <s:Button id="close" label="Close" click="close_clickHandler(event)"/> 
                      <s:DataGrid id="queries" columns="{_col}"/>
                  </s:BorderContainer>
              </mx:Module>
              
              • 4. Re: Datagrid column in module causing memory leak
                Flex harUI Adobe Employee

                Just declare a varialbe of type GridColumn in the main app somewhere (and import GridColumn)

                • 5. Re: Datagrid column in module causing memory leak
                  JamesEco Level 1

                  That fixes the problem. I've used the same thing in my real application and the modules are now unloading correctly.

                   

                  Thank you so much!

                   

                  Kind regards

                   

                  James

                  • 6. Re: Datagrid column in module causing memory leak
                    JamesEco Level 1

                    I assume this needs to be filed as a bug then?

                    • 7. Re: Datagrid column in module causing memory leak
                      Flex harUI Adobe Employee

                      Sure, file a bug and we’ll investigate more later.

                      • 8. Re: Datagrid column in module causing memory leak
                        Jeff ZM Li Level 1

                        Hi JamesEco, I went into the same problem, this bug hasn't been fixed yet. I don't know how you import and fix the problem and now I am using the mx DataGrid, could you please give a bit details?

                         

                        Regards,

                         

                        Jeff Li

                        • 9. Re: Datagrid column in module causing memory leak
                          JamesEco Level 1

                          Hi Jeff

                           

                          I wasn't using the mx:DataGrid, so I don't know if it is the same, but all I needed to do was declare a private var of type s:GridColumn, in the class that was loading the module, and obviously make sure it brings in the import statement. Then all memory leaks disappeared

                           

                          Hope that helps

                           

                          James

                          • 10. Re: Datagrid column in module causing memory leak
                            Jeff ZM Li Level 1

                            Hi James,

                             

                            I did still not figure out "make sure it brings in the import statement" means. I tried to declare the following in multiple locations:

                            <fx:Declarations>

                                  <s:GridColumn id="TestGrid" dataField="accountBalanceCents" headerText="Account" />

                            </fx:Declarations>


                            and in my module, I did the following:

                            <s:DataGrid id="idTransGrid" requestedRowCount="5" >

                                  <s:columns>

                                       <s:ArrayList>

                                                 <s:GridColumn >{ ????.TestGrid }</s:GridColumn>

                                      </s:ArrayList>

                                 </s:columns>

                            </s:DataGrid>


                            All different location's binding works well, just the module can't do GC.

                            Thanks


                            Jeff


                            • 11. Re: Datagrid column in module causing memory leak
                              Jeff ZM Li Level 1

                              Thanks James,

                               

                              I sort it out now.

                               

                              Best Regards.

                               

                              Jeff Li