9 Replies Latest reply on Apr 10, 2007 10:43 PM by jpwrunyan

    PopUpManager.removePopUp() method cannot free up memory

    ncelq
      HI All,

      i have followed the examples from livedoc for dealing with popup windows:

      Flex 2 Developer's Guide > Building User Interfaces for
      Flex Applications > Using Layout Containers > TitleWindow layout container > Using the PopUpManager to create a TitleWindow container

      here is the code:

      <?xml version="1.0"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml">
      <mx:Script>
      <![CDATA[
      import mx.managers.PopUpManager;
      import mx.core.IFlexDisplayObject;

      private var helpWindow:IFlexDisplayObject;

      private function showLogin():void {
      // Create the TitleWindow container.
      helpWindow = PopUpManager.createPopUp(this, MyLoginForm, false);
      }

      private function removeForm():void {
      PopUpManager.removePopUp(helpWindow);
      }
      ]]>
      </mx:Script>

      <mx:VBox width="300" height="300">
      <mx:Button click="showLogin();" label="Login"/>
      <mx:Button id="b2" label="Remove Form" click="removeForm();"/>
      </mx:VBox>
      </mx:Application>

      It is found that, after creating a new popup windows, the memory allocation (task manager) for IE increased; then i have clicked the remove form button and invoke PopUpManager.removePopUp() function, it is found that the memory cannot be released!

      I have tried to open popup -> remove popup -> open popup -> remove popup ..... for many times, the memory usage keep increasing ! even if i wait for an hour, the memory usage remain the same.

      Is it a memory leakage for flash player 9? or do i need to write some other code in order to free the memory after closing the popup windows.

      Thanks


        • 1. Re: PopUpManager.removePopUp() method cannot free up memory
          jtan Level 1
          We have seen this problem and there is a bug logged in our bugbase about this. What I've seen is that the memory does go down when you remove a popup using the removePopUp method. However, it doesn't go down to the original memory. For example, an application my work like this:

          (on startup)
          memory - 11000K

          (after opening over 25 popups)
          memory - 42000K

          (after closing all of the popups)
          memory - 29000K

          If this is not the behavior you are seeing, let me know.

          Joan Lafferty
          Flex SDK QA
          • 2. Re: PopUpManager.removePopUp() method cannot free up memory
            jpwrunyan Level 1
            Is there any time frame for fixing this bug?
            I'm particularly concerned by it because the current application I am developing has a lot of popups and the end user will be using it all day long... I don't want to tell them they have to close the browser and reload once or twice a day.

            Also, does this issue exist when using addChild / removeChild? It seems a possible work-around would be to implement my own PopUpManager (bypassing Flex's) using these two methods. This admittedly defeats the purpose of having a PopUpManager available in the first place...
            • 3. Re: PopUpManager.removePopUp() method cannot free up memory
              jpwrunyan Level 1
              To Joan and anyone else,
              PopUpManager indeed does not seem to free up resources as promised. In fact, it seems to make sure you can't free them no matter what.

              I have a popup class with a lot of "heavy" components in it so I can watch the memory go up easily (after like 5-10 popups, 100,000 k increase in memory).

              Here is a dumbed down version of the methods I use:

              private var popup:TitleWindow;

              private function someButtonClickHandler():void {
               popup = mx.managers.PopUpManager.createPopUp(this, HeavyPopUpClass) as TitleWindow;
               popup.addEventListener(CloseEvent.CLOSE, closeHandler, false, 0, true); //whether the ref is weak or strong makes no diff.
              }

              public function closeHandler(e:CloseEvent):void {
               popup.removeEventListener(CloseEvent.CLOSE, closeHandler, false);
               PopUpManager.removePopUp(popup); //popup disappears and SHOULD be gone from memory
               popup = null; //the popup may still survive because of this reference so I set it to null as well.
               //now the popup should definately be gone... but it isn't.
              }

              <mx:Button click="someButtonClickHandler()" />

              Now according to everything I have read, there is no reason why the popup instance should not be collected as garbage. I only used weak references on the listeners, I called removePopUp(), and I even set its only other reference to null. But the memory usage does not change even when I force a mark/sweep of the GC. This is currently crippling my project. Am I missing something? What gives?
              • 4. Re: PopUpManager.removePopUp() method cannot free up memory
                jpwrunyan Level 1
                Found out two additional things:
                1) This bug only manifests itself if I open the popup from an .swf that is loaded via SWFLoader
                2) According to Adobe support, the IE Flash Player has a bug where GC doesn't get called until memory exceeds 1.6 gigs (kinda strange...)
                • 5. Re: PopUpManager.removePopUp() method cannot free up memory
                  jpwrunyan Level 1
                  Joan got back to me! Kudos!
                  Here is what she said:



                  We have had a lot of people comment against PopUpManager and we have made improvements in it's memory consumption. These improvements should all be in Flex 2.01. If I use your code and load a PopUp with nothing in it (to test just the PopUpManager), I can open and close the PopUp and get the memory to increase only a little bit and then it goes down for the most part. All of the memory isn't released,however. According to our developer, when you first open a popup, this is when the PopUpManager is loaded, so all of this memory from the first open is never fully released. Otherwise, the memory usage when you open and close a PopUp goes up and down showing that Garbage collection is working.

                  We do have some bugs open with memory leaks on other components that you may be seeing in your application. We have a bug open regarding memory leaks with the DateField, using Bindings, and the flash TextField which is the base class for some of our components like TextInput.
                  • 6. Re: PopUpManager.removePopUp() method cannot free up memory
                    GMina
                    OK, i have this same exact problem, and I am running Flex Builder 2.0.1!

                    I can execute the following code:

                    var test : IFlexDisplayObject = PopUpManager.createPopUp(this,TitleWindow);
                    PopUpManager.removePopUp(test);

                    And the memory usage just keeps going up, it will NEVER release it. This appears to be a very substantial bug, eh? Anyone know whats up with this?
                    • 7. Re: PopUpManager.removePopUp() method cannot free up memory
                      jpwrunyan Level 1
                      The PopUpManager thing is something they didn't fix in 2.0.1 although it is reportedly getting better. Quite honestly, I don't see how they can do away with it completely since you have to load the PopUpManager to use it. And if you use it once, it just makes sense to keep in in memory since you will probably use it again. The leak is not that critical.

                      That said, I might suggest that the major leak you are experiencing is something else. You have to be careful about the listeners and references you use with popups and make sure that everything gets nulled out. Otherwise if even one reference exists, the TitleWindow instance remains in memory and the same code will just pile more and more of the same instance into memory. This is an issue with every instance of every thing in Flex--not just popups.

                      1) use weak reference for addEventListener() with dynamically created content
                      2) keep track of references and set them to null when you remove components from the display list (permanently)

                      I can honestly assure you that (other than the manager's memory) I am able to garbage collect memory used by popups. It was a big issue for me, as well. By Adobe's own admission, there is some leakage, but not significant.
                      • 8. Re: PopUpManager.removePopUp() method cannot free up memory
                        GMina Level 1
                        I actually tracked down the bug. It isn't directly relating to the PopUpManager. The leak only occurs when I use a ViewStack inside the class I am loading with the PopUpManager. I found a hack on some japanese Flex site to extend the ViewStack and correct (or workaround) the memory leak. Once I started using my "new" version of ViewStack I was able to retrieve about 95% of memory consumed by the popup. Here is the code if anyone wants to look at it:

                        package myPack
                        {
                        import mx.containers.ViewStack;
                        import mx.managers.ISystemManager;

                        public class NewViewStack extends ViewStack
                        {
                        private var commitingProperties : Boolean = false;

                        override protected function commitProperties():void {
                        commitingProperties = true;
                        super.commitProperties();
                        commitingProperties = false;
                        }

                        override public function get systemManager() : ISystemManager {
                        if (commitingProperties && !historyManagementEnabled) {
                        //prevent memory leak!!!
                        return new DummySystemManager();
                        }
                        return super.systemManager;
                        }

                        }
                        }


                        /************************* DUMMY CLASS *************/
                        package com.connectfirst.intelliqueue.utils
                        {
                        import flash.display.MovieClip;
                        import flash.display.Sprite;
                        import flash.geom.Rectangle;
                        import flash.text.TextFormat;

                        import mx.core.IChildList;
                        import mx.managers.IFocusManagerContainer;
                        import mx.managers.ISystemManager;

                        public class DummySystemManager extends MovieClip implements ISystemManager {
                        public function create(... params):Object { return null; }
                        public function info():Object { return null; }
                        public function get cursorChildren():IChildList { return null; }
                        public function get document():Object { return null; }
                        public function set document(value:Object):void {}
                        public function get embeddedFontList():Object { return null; }
                        public function get focusPane():Sprite { return null; }
                        public function set focusPane(value:Sprite):void {}
                        public function get numModalWindows():int { return 0; }
                        public function set numModalWindows(value:int):void {}
                        public function get popUpChildren():IChildList { return null; }
                        public function get rawChildren():IChildList { return null; }
                        public function get screen():Rectangle { return null; }
                        public function get toolTipChildren():IChildList { return null; }
                        public function get topLevelSystemManager():ISystemManager { return null; }
                        public function addFocusManager(f:IFocusManagerContainer):void {}
                        public function removeFocusManager(f:IFocusManagerContainer):void {}
                        public function activate(f:IFocusManagerContainer):void {}
                        public function deactivate(f:IFocusManagerContainer):void {}
                        public function getDefinitionByName(name:String):Object { return null; }
                        public function isTopLevel():Boolean { return false; }
                        public function isFontFaceEmbedded(tf:TextFormat):Boolean { return false; }
                        }

                        }
                        • 9. Re: PopUpManager.removePopUp() method cannot free up memory
                          jpwrunyan Level 1
                          quote:

                          Originally posted by: GMina
                          The leak only occurs when I use a ViewStack inside the class I am loading with the PopUpManager. I found a hack on some japanese Flex site to extend the ViewStack and correct (or workaround) the memory leak. Once I started using my "new" version of ViewStack I was able to retrieve about 95% of memory consumed by the popup. Here is the code if anyone wants to look at it:


                          I don't suppose you could post the link? I also had a memory leak with ViewStack when using modules and ended up ditching the component for my own work-around. However, I would like to show the issue to some Japanese co-workers.