1.08.2009

Heisenberg on Garbage Collection

Detecting if a reference gets garbage collected is tricky. In general, you cannot do this because of the Heisenberg Uncertainty Principle -- if you hold a reference, then it cannot get GCd; if you don't hold it, then you cannot check if it got GCd. Until now :)

Example (try uncommenting the line which nulls our important reference):

// the object we're curious about
var impReference:Object = new Object();
public function init():void
{
// this code monitors an object for GC, giving it a name.
monitorGC("impReference", impReference);
//impReference = null; // try uncommenting me

// GC rarely occurs until after code runs, after a frame or so
callLater(function():void
{
// call twice USUALLY makes a GC occur, as does opening
// a LocalConnection to the same name twice in a row
System.gc();
System.gc();
// look at the error console
if (checkIfGCd("impReference"))
trace(name + " got GCd")
});
}

// support code
static public function monitorGC(name:String, reference:*):void
{
// this is how we get around Heisenberg, a strong Dictionary holding
// weak dictionaries, each holding a single reference, or no references
(gcReferences[name] = new Dictionary(true))[reference] = true;
}

static public function checkIfGCd(name:String):Boolean
{
var gotGCd:Boolean = true;
for (var foo:* in gcReferences[name])
gotGCd = false;
return gotGCd;
}

static private const gcReferences:Dictionary = new Dictionary();