Memory leak caused by setTimeout

I have a Cairngorm-based application that polls a server for data every few seconds.  To do this I have a command that initiates the server request, and in the result handler I set a timeout.  When that timeout is up, I dispatch the event that is responsible for kicking off the command in the first place.  It looks something like this:

public class PollServerCommand
{
   public function execute(event:CairngormEvent):void
   {
      // Create and call delegate 
   }
 
   public function result(data:Object):void
   {
      // Process data...
      setTimeout(2000,poll);
   }
 
   private function poll():void
   {
      var pollEvent:PollEvent = new PollEvent();
      pollEvent.dispatch();
   }
}

This results in lots of commands being created, but in theory the garbage collector should be cleaning up the old ones every so often.  Well, that’s not really the case.  While profiling my app, I noticed that every polling command I created stayed in memory.  The solution?  Swapping out the calls to setTimeout for instances of the Timer class like so…

public function result(data:Object):void
{
   var pollTimer:Timer = new Timer(2000,1);
   pollTimer.addEventListener(TimerEvent.TIMER,poll);
   pollTimer.start();
}
 
private function poll(event:TimerEvent):void
{
   var pollEvent:PollEvent = new PollEvent();
   pollEvent.dispatch();
}

I’ve always known that the Timer class was preferred over setTimeout, but now I know why. Can anyone from the Flash Player Team shed some light on why setTimeout is keeping these objects alive?

This entry was posted in Flex and tagged , . Bookmark the permalink. Both comments and trackbacks are currently closed.

5 Comments

  1. Posted September 5, 2008 at 7:12 am | Permalink

    Have you tried saving the timeout ID and then force clearing it using clearTimeout() in the poll() method? Does it still keep the instances in memory?

  2. Posted September 5, 2008 at 2:04 pm | Permalink

    You’re right, Richard. Calling clearTimeout does allow the commands to become eligible for garbage collection. It’s odd that this call is necessary to clear the references that are keeping it alive. Once a timeout ends, I would expect the player to do whatever clearTimeout is doing behind the scenes since that timeout won’t be used again. Thank you for your suggestion.

  3. Posted September 17, 2008 at 2:30 am | Permalink

    I think the local timer variable is the source of memory leak.

    var pollTimer:Timer

    you should turn it to a global variable, and the whole app has only one timer, one is enough!

  4. Posted September 25, 2008 at 1:17 pm | Permalink

    In this case one timer would definitely be enough. In the end I simplified things further by only having one instance of my command. When the timer ticks out I call execute again rather than re-dispatching the event. I just found is problematic that something that looked like it should have been garbage collected wasn’t.

  5. Posted December 21, 2010 at 1:41 am | Permalink

    “Calling clearTimeout does allow the commands to become eligible for garbage collection. It’s odd that this call is necessary to clear the references that are keeping it alive. Once a timeout ends, I would expect the player to do whatever clearTimeout is doing behind the scenes since that timeout won’t be used again. Thank you for your suggestion.”
    Where I have been able to read about this?