Weak Activation Object

It appears either A) The Activation Object in ActionScript 3 is dumber than it’s predecessor, or B) the new Garbage Collector implemented in Flash Player 8 is more aggressive, or C) I’ve never had this use case. Naturally, I’d like to believe that it’s A, but I have a sinking suspicion it’s a combination of B & C.

I read this post by Matthew Tretter describing how reference-less objects such as Tweens and URLLoader’s won’t work consistently when there are no references to them.  This is because they have no references, and when the Garbage Collector comes around, he sees this, and destroys the mofo’s. This is in direct violation of how a lot of us have coded in the past since Flash Player 6 implemented dynamic MovieClip methods like onPress, and onRelease. Using anonymous functions with anonymous variables was just the lay of the land:

my_mc.onPress = function()
{
    var my_xml = new XML();
    my_xml.ignoreWhite = true;
    my_xml.onLoad = function(success)
    {
       trace("success!, parse this.");
    };
}

In the above example, my_xml is a local variable. In ActionScript 1 and 2, no one has a reference to it. Thus, at the end of onPress, it’ll die… or, so it would appear. However, Garbage Collection first has to activate to kill it; theoretically GC only runs every 60 seconds, or when memory increases 20% in 1 frame. The GC will kill it if no one has a reference to it. However, the Activation Object does. For both XML and LoadVars, I and thousands of other Flash Developers have used this technique with a variety of ways to handle scope as well.

You’ll notice, however, that this code isn’t very memory intensive, thus I guess staying under the radar of GC. It merely makes an XML object, gets the XML, parses it, and that’s it, done. When AS2 came out, I started keeping class references to these variables for ease of writing code, and confirmation I was in fact deleting them later when I was done. Therefore, my guess as to why I’ve never seen the problem Matthew talks about is that I’ve never created extremely memory intensive applications pre-AS2 that used of asynchronous operations created via local variables. Seems plausible.

So, I told him he was wrong and moved on. He tracked my ass down to Flashmedia to politely plead his case. Turns out I was wrong… and extremely lazy. I didn’t do diligence and actually test his code. Upon testing his code (1000 creations vs. my 1), and his problem was easily reproducible. He’s created some classes that help encapsulate this so you don’t have to worry about it.

For example, Robert Penner’s original Tween classes actually kept a global reference of all crated Tween instances in a static array, so there was always at least 1 reference. I had just always assumed that the Activation Object knew of asynchronous objects, and thus released the lock (killed the reference) on it after their asynchronous operation had completed such as onData, or onLoad for LoadVars/XML.

I often create local variables for loading such as Loader or URLoader for generic loading code, so I was horrified that this scenario was this predictable. I’m not sure how to best resolve this yet since I’ve been doing this for years and it’ll really be a pain in the ass to start either keeping class references for these things or using a wrapper class. I only load 1 or 3 of these at any one time, not 1000 so maybe I’ve just gotten lucky all of these years. Maybe a beer will help… yeah… a beer…

Anyway, I apologize Matthew for saying you were wrong without due diligence on my part; I was wrong and could of at least had the common courtesy to actually test your provided code before making judgments based on long held assumptions.

2 Replies to “Weak Activation Object”

  1. I’d like to say that your humility in admitting when you’re wrong is appreciated by all…your daughter has a good daddy.

  2. I definitely sympathize with the shock of: “What!? I can’t do this anymore?” I would say, though, that this is another case where the strictness of AS3 encourages better practices. If you look at this issue through the lens of, “How can I minimize memory leaks?”, things come into focus. The AS2 local variable approach is more convenient up-front, but it easily leads to memory leaks.

    > Robert Penner’s original Tween classes actually kept a global reference of all crated Tween instances in a static array, so there was always at least 1 reference.

    I assume you’re referring to MovieClip._listeners (to which MovieClip.addListener() adds the AS2 Tween instance). Yes, the reference there allows you to use local variables for Tweens without being garbage collected, but it has its own undesirable side effects. An AS2 Tween can get stranded in MovieClip._listeners, where it keeps running and there’s no way to tell it to stop. If you aren’t careful (e.g. “always stop() the Tween first), you can get all kinds of anonymous Tween objects floating around. In some cases, they would actually be fighting over the same movie clip.

    To me, having an object in memory “still doing stuff”, but beyond my script’s control, is kinda creepy. It’s like the planet in “Aliens” that has broken off all communications. As Ripley intoned:
    “I say we take off and nuke the entire site from orbit. It’s the only way to be sure.”

    The AS3 garbage collector is basically Ripley. If your object needs to be alive and doing stuff, keep a line of communication open. Otherwise, yousa object gonna die. It’s the price we pay to avoid memory leaks and crappy sequels.

Comments are closed.