Running Timers are not Garbage Collected. Ever.

On a certain mailing list, something was mentioned about Timers, cleaning up, garbage collection, etc. Arno Gourdol from the Adobe AIR Team made the following statement:

Just to be clear: even if you have no references to a Timer, as long as the timer is running, it will not be Garbage Collected (think of it as if the runtime was keeping a reference to running timers).

That was interesting to me, and as it recently came up on another mailing list, I thought I’d do a little test.

Here, I create a Timer and a Sprite as local variables. The timer has a weak-referenced listener for the Timer event, and the sprite has a weak-referenced listener for the enterFrame event. I let them run for a second and then force garbage collection using a trick Grant Skinner mentioned a while back.

At that point, you can see the enterFrame stops firing, as the sprite has been garbage collected and ceases to exist. However, the timer continues running forever, as Arno’s statement predicts.

[as]package {

import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.net.LocalConnection;
import flash.utils.*;

public class TimerTest extends Sprite{

public function TimerTest(){
var timer:Timer = new Timer(30);
timer.addEventListener(TimerEvent.TIMER, tick, false, 0, true);
timer.start();

var s:Sprite = new Sprite();
s.addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);

setTimeout(killEm, 1000);
}

private function tick(event:TimerEvent):void
{
trace(“tick”);
}

private function onEnterFrame(event:Event):void
{
trace(“enterFrame”);
}

private function killEm():void
{
trace(“kill…..”);
try
{
new LocalConnection().connect(‘foo’);
new LocalConnection().connect(‘foo’);
}
catch (e:*)
{
}
}
}
}
[/as]

Just thought that was interesting and might come in handy someday.

This entry was posted in Flash. Bookmark the permalink.

6 Responses to Running Timers are not Garbage Collected. Ever.

  1. iiley says:

    Hi, thanks for give the message from Adobe team, Arno Gourdol’s statement is very helpful.
    But your test will not care weak-referenced or not, with strong-referenced listener, we get same result.

  2. nice post (as usual)
    can you explain the killEm function a bit more?
    how is the localConnection forcing the garbage
    collector to do its thing? that might be its own
    blog post though… thanx!

  3. kp says:

    the local connection thing is a hack to force garbage collection, described here: http://gskinner.com/blog/archives/2006/08/as3_resource_ma_2.html

    It’s not something you should use in live code, but useful to test stuff like this.

  4. In AIR, although not in Flash, you can use System.gc() to trigger garbage collection. It should still be called twice in a row, however, if you want everything possible to be collected immediately.

    Oliver Goldman | Adobe AIR Engineering

  5. Alex Bustin says:

    I always thought of Timer as being a simple proxy for setInterval. And thus inheriting the same setInterval dangers.

    Maybe we can try to build a new Timer class without the dangers clearInterval never being called.

  6. All well and good, but how do you solve this problem? How can you completely kill and remove a running Timer?
    For example: I have a class on stage which includes a timer. When the class is removed from the stage the timer keeps running unless you manually remove it first.

Leave a Reply