In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Memory leak unit test

http://blog.onthewings.net/2010/10/18/how-to-know-objects-are-really-gced-in-flash-as3/
Get Adobe Flash player
by andyli 22 Oct 2010
/**
 * Copyright andyli ( http://wonderfl.net/user/andyli )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ohTv
 */

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.utils.setTimeout;
    
    public class FlashTest extends Sprite {
        private var trash:Trash = new Trash();
        private var tf:TextField;
        
        public function FlashTest() {
            tf = new TextField();
            tf.width = stage.stageWidth;
            tf.height = stage.stageHeight;
            addChild(tf);
            
            tf.appendText("Add 100 random garbage...\n");
            
            for (var i:uint = 0 ; i < 100 ; ++i){
                var myObj:* = {test:i}; //create something that will be GC'ed later...
                
                //maybe some operation on myObj here
                
                trash.throws(myObj);
            }
            
            checkGC();
            
            //some more operations if you want...
            
            Trash.collectAll();
            
            tf.appendText("1ms later...\n");
            
            setTimeout(checkGC,1);
        }
        
        public function checkGC():void {
            tf.appendText("Number of garbage: " + trash.garbages().length + "\n");
        }

    }
}

//haXe implementation: http://gist.github.com/632717
/*
    A Trash that you can throw unused objects inside and see if they are GC'ed later.
    http://blog.onthewings.net/2010/10/18/how-to-know-objects-are-really-gced-in-flash-as3/
*/
import flash.utils.Dictionary;
import flash.system.System;
import flash.net.LocalConnection;

class Trash {
    public function Trash() {
        dict = new Dictionary(true);
    }

    /*
        Throws a garbage, an unused object that should be GC'ed soon, to the Trash.
        An optional identifier that let you know what is in the Trash by garbages().
    */
    public function throws(garbage:*, identifier:String = null):void {
        dict[garbage] = identifier == null ? garbage.toString() : identifier;
    }

    /*
        Return an Array of identifier of the garbages inside.
        It does not let you pick out the garbages, since they are dirty, and you shouldn't hold reference of them again.
    */
    public function garbages():Array {
        var ary:Array = [];
        for each(var i:String in dict) {
            ary.push(i);
        }
        return ary;
    }

    /*
        Tell if the Trash is empty.
    */
    public function isEmpty():Boolean {
        for each(var i:String in dict) return true;
        return false;
    }

    /*
        Trigger GC.
    */
    static public function collectAll():void {
        //System.gc(); //it does not collect all the garbages...

        // unsupported hack that seems to force a *full* GC
        try {
            var lc1:LocalConnection = new LocalConnection();
            var lc2:LocalConnection = new LocalConnection();
            lc1.connect('name');
            lc2.connect('name');
        } catch (e:Error) { }
    }

    private var dict:Dictionary;
}