6 Replies Latest reply on Apr 24, 2007 6:00 PM by jspiro

    PopUpManager memory leak - BUG CONFIRMED!

    GMina
      I am not sure how Adobe goes about logging bug reports, but I have tracked down a serious memory leak in the PopUpManager class. I have worked up a little two file application which will demonstrate the problem. The first file contains a Timer object which fires every 50 milliseconds. Each time it fires it executes the createPopUp() and removePopUp() methods of the PopUpManager. The values of System.totalMemory are neatly displayed at the bottom so you can see when the leak occurs and when it doesn't.

      The createPopUp() method uses the LeakTest.mxml class which is simply a <TitleWindow> with 10 <ComboBox> elements inside. When you run the test you will see that the memory just keeps going up and up and up and up until finally the browser will crash.

      Here is the VERY interesting thing... If you comment out a single <ComboBox> from the LeakTest.mxml file you will see tha the memory leak no longer occurs. The system is able to take back the memory and the total memory consumption does NOT sky rocket... WTF??? Apparently 10 is just one too many?

      ***********************************************************
      ***************** FILE: MemoryLeakTest.mxml**********
      ***********************************************************
      <?xml version="1.0"?>
      <mx:Application
      xmlns:mx=" http://www.adobe.com/2006/mxml"
      xmlns:local="*"
      creationComplete="createComplete()">


      <mx:Script>
      <![CDATA[
      import mx.formatters.NumberFormatter;
      import mx.core.IFlexDisplayObject;
      import mx.managers.PopUpManager;

      [Bindable]
      public var initialMemory:Number = System.totalMemory;

      [Bindable]
      public var currentMemory:Number = System.totalMemory;

      [Bindable]
      public var maxMemory:Number = System.totalMemory;

      [Bindable]
      public var windowsOpened:Number = 0;


      public var timer:Timer = new Timer(50);

      [Bindable]
      public var format:NumberFormatter = new NumberFormatter();

      public function createComplete():void{
      timer.addEventListener("timer",startTest);
      format.precision = 0;
      }

      public function startTest(event:TimerEvent):void{
      windowsOpened++;
      currentMemory = System.totalMemory;
      if(currentMemory > maxMemory){maxMemory = currentMemory;}

      // will produce a memory leak!!!!
      var window:IFlexDisplayObject = PopUpManager.createPopUp(this,LeakTest,false);

      //will not produce a memory leak!!!!
      //var window:IFlexDisplayObject = PopUpManager.createPopUp(this,NoLeakTest,false);

      PopUpManager.removePopUp(window);
      }

      ]]>
      </mx:Script>

      <mx:VBox>
      <mx:Button label="Start Test" click="timer.start();"/>
      <mx:Button label="Stop Test" click="timer.stop();"/>
      <mx:Label text="Current Memory Usage: {this.currentMemory/1024}"/>
      <mx:Label text="Maximum Memory Usage: {this.maxMemory/1024}"/>
      <mx:Label text="Departure from Initial Consumption: {this.format.format((this.initialMemory/(this.currentMemory-this.initialMemory))*100)}%"/ >
      <mx:Label text="Windows Opened: {this.windowsOpened}"/>
      </mx:VBox>
      </mx:Application>


      ***********************************************************
      ***************** FILE: LeakTest.mxml *****************
      ***********************************************************
      <?xml version="1.0" encoding="utf-8"?>
      <mx:TitleWindow xmlns:mx=" http://www.adobe.com/2006/mxml" width="400" height="300">
      <mx:VBox>
      <mx:ComboBox>
      <mx:Array>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      </mx:Array>
      </mx:ComboBox>
      <mx:ComboBox>
      <mx:Array>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      </mx:Array>
      </mx:ComboBox>
      <mx:ComboBox>
      <mx:Array>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      </mx:Array>
      </mx:ComboBox>
      <mx:ComboBox>
      <mx:Array>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      </mx:Array>
      </mx:ComboBox>
      <mx:ComboBox>
      <mx:Array>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      </mx:Array>
      </mx:ComboBox>
      <mx:ComboBox>
      <mx:Array>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      </mx:Array>
      </mx:ComboBox>
      <mx:ComboBox>
      <mx:Array>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      </mx:Array>
      </mx:ComboBox>
      <mx:ComboBox>
      <mx:Array>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      </mx:Array>
      </mx:ComboBox>
      <mx:ComboBox>
      <mx:Array>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      </mx:Array>
      </mx:ComboBox>
      <mx:ComboBox>
      <mx:Array>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      <mx:Object label="1" data="1"/>
      </mx:Array>
      </mx:ComboBox>
      </mx:VBox>
      </mx:TitleWindow>
        • 1. Re: PopUpManager memory leak - BUG CONFIRMED!
          GMina Level 1
          one other question... why is the Adobe forum the one place where you can't use code formatting!!! so annoying.
          • 2. Re: PopUpManager memory leak - BUG CONFIRMED!
            VarioPegged Level 2
            When I slow the firing of the timer event down to 300 - 500 ms, it appears that the memory leak stops with your 10 combobox elements. That would indicate to me that perhaps the Flash Player isn't able to get rid of the popups fast enough at 50 milliseconds. I even tested it with 20 combobox elements at 300 ms, and no apparent memory leak.

            TS
            • 3. Re: PopUpManager memory leak - BUG CONFIRMED!
              GMina Level 1
              That is useful information... but why do 9 elements work fine, but 10 causes a leak? The GC should NOT be dependant on the speed at which objects are created. The elements have all references broken, regardless of how fast they were created. The GC should still remove them from active memory, correct?
              • 4. Re: PopUpManager memory leak - BUG CONFIRMED!
                GMina Level 1
                TS -
                I took your queue to do some further testing, and it appears that this is probably not a memory leak at all... but a 'bug' with the Flash player GC. Apparently it will never take CPU cycles to perform garbage collection. The 50ms just wasn't enough time for GC to fire. It will just continue to consume free RAM until the browser crashes... even though it has many M of memory being consumed by objects which should be discarded. If you stop the test momentarily and start it back the GC will kick in when there is some free time...

                Although this test proves something... don't really know what... I am not sure it really relates to real world Flex applications. I can't think of a scenario where you would ever have a requirement to start creating objects and not ever stop, right?

                I would still like a comment from an Adobe engineer on this situation... perhaps it has further ramifications that we aren't realizing here.

                Thanks for the second set of eyes on this.
                -Geoff
                • 5. Re: PopUpManager memory leak - BUG CONFIRMED!
                  JabbyPandaUA Level 3
                  You can submit bugs related to Flex SDK here:
                  http://www.adobe.com/cfusion/mmform/index.cfm?name=wishform

                  ps
                  Adobe forums engine sucks, I agree, that's probably why many people prefer using Flexcoders and Flexcomponents Yahoo newsgroup :)
                  • 6. Re: PopUpManager memory leak - BUG CONFIRMED!
                    jspiro
                    This test doesn't demonstrate any leaks in PopUpManager or ComboBox. What you are experiencing is the intended behavior of the Flash Player and its GC: CPU time is optimized for smooth drawing and animation performance, then for user interaction, and then for anything else (opposite behavior than a typical desktop app where the sound or animation might skip in lieu of other activities).

                    If drawing requires most of the CPU (in this case, for drawing and destroying popups at 50ms intervals), only whatever IDLE time is left will be allocated for the GC. The effect is that memory will be cheaply allocated and uncollected, appearing like a leak. The assumption is that the app or movie will eventually breathe -- even for a few hundred ms -- interactive applications definitely do this, and most animations don't use 100% CPU indefinitely.

                    Timers generate tons of garbage on their own, even if you don't do anything... if you fire them fast enough (1ms); and you'll see this effect if you bump the framerate up high enough (try 1000) even if you're doing almost nothing. 500ms is usually a good balance between your patience and giving the GC time to catch up; 1 second is still unrealistic (for an interactive app), but a good value to be sure you're isolating memory creep (do some pushups while you wait ).

                    Jono