1 Reply Latest reply on Jul 24, 2010 11:59 PM by Flex harUI

    Huge Memory Leak - Simple To Reproduce

    ycagwyw

      I have an application that updates the display every so often using a timer, and as I run the application it comsumes increasingly more memory. After some extensive effort I narrowed it down to a very simple scenario:

       

      The code below creates a 40x30 matrix of objects that extend UIComponent (the same problem exists if I extend Sprite). A timer fires every 3 seconds and repaints each object with a random color on updateDisplayList(). Running this (whether from Flex IDE or swf) produces an infinitely increasing memory leak, even though no new memory should be allocated on each timer event. I see an increase of roughly .5MB to 1MB with each call. Calling gc() explicitly (which I know I shouldn't) doesn't help. I'm using Flex Builder 3.

       

      What am I missing? Is this a known bug? Any comment would be greatly appreciated.

       

       

      <?xml version="1.0"?>
      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="startUp();" horizontalAlign="left">

          <mx:Script>
              <![CDATA[
             
               private var _myUIObjects:Array = new Array();
              
                  private var _timer:Timer = new Timer(3000);
                 
                  private function startUp():void
                  {
                   var myUIObject:MyUIObject;
                  
                   for (var i:int = 0; i < 1200; i++) {
                    myUIObject = new MyUIObject();
                    _myUIObjects.push(myUIObject);
                    canvas.addChild(myUIObject);
                   }
                  
                   for (var iRow:int = 0; iRow < 30; iRow++) {
                    for (var iCol:int = 0; iCol < 40; iCol++) {
                     myUIObject = _myUIObjects[iRow * 40 + iCol];
                     myUIObject.x = iCol * 18;
                     myUIObject.y = iRow * 18;
                     myUIObject.width = 15;
                     myUIObject.height = 15;
                    }
                   }             
                  
                    _timer.addEventListener(TimerEvent.TIMER, handle_timer);
                    _timer.start();
                  }
                 
                  private function handle_timer(event:Event):void
                  {
                   for (var i:int = 0; i < 1200; i++) {
                    MyUIObject(_myUIObjects[i]).invalidateDisplayList();
                   }
                  }
              ]]>
          </mx:Script>
         
          <mx:Canvas id="canvas" width="1000" height="1000"/>
         
      </mx:Application>

       

       

      package
      {
      import mx.core.UIComponent;

      public class MyUIObject extends UIComponent
      {
        protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
        {
         this.graphics.beginFill(Math.random() * 500000);
         this.graphics.drawRect(0,0,15,15);
        }
      }
      }