1. To remove an object (to authorize Flash Player to garbage collect it in the next GC cycle), simply remove the references to the object by doing so:
var fruit:Fruit= new Apple();
fruit = null;
or reuse the reference and stuff it with another object, like so:
fruit = new Orange();
2. Since garbage collection of a large amount of objects will be a big performance hit, rule of thumb is, you should strive to reuse rather than to delete an object for GC whenever possible.
3. When the programmer authorizes FP to garbage collect an object, he should always remember the followings:
- Remove all the event listeners of the target before removing it;
- Remove all the intervals, timers (Timer/timeout) that are associated with the object;
- Remove all the timeline functions within the instances of DisplayObject that are associated with the object;
- Remove all the tween instances and onEnterFrame handlers that are associated with it.
- URLLoader is also on the blacklist as some people noticed.
Example:
Before refactoring:
public function set tweenPosX(v:Number):void
{
//var duration:Number = UNIT_DIST_DURATION*Math.abs(v-posY);
var duration:Number = .5;
//if(duration==0)return;
var tween:Tween = new Tween(this, “posX”, Regular.easeInOut, posX, v, duration, true);
tween.addEventListener(TweenEvent.MOTION_FINISH, tweenPosXFinish);
}
The code above is problematic since tween is a local variable and it registers function tweenPosXFinish() within the setter function. When the setter function finishes execution, tween is disposed of for GC while its TweenEvent listener is not. The listener object will take up more and more memory as consecutive calls to the setter function until the next mark/sweep GC process occurs. both tween and its listener function remain in memory; all the instances get stacked with sequential tweening until the next Mark/Sweep process occurs. The app takes up around 6mb (”6,569,984″) memory in standalone player and continues to take up more memory with sequential calls to the setter/tweening function until it reaches around 8mb(”7,909,376″, etc.); In a fresh web browser (without other tabs/windows open), it starts taking around 2mb (”2,093,056″) with similar situation until the memory usage reaches around 3mb (”3,133,440″). GC doesn’t seem to be able to get rid of the local references to a tween instance. I came up with this conclusion because using weak references to the listeners of the tween didn’t solve the issue; so it presumably was not listener issue.
After refactoring: tween_posX becomes instance variable and GC is reused.
private var tween_posX:fl.transitions.Tween;
public function set tweenPosX(v:Number):void
{
//var duration:Number = UNIT_DIST_DURATION*Math.abs(v-posY);
var duration:Number = .5;
tween_posX = new Tween(this, “posX”, Regular.easeInOut, posX, v, duration, true);
tween_posX.addEventListener(TweenEvent.MOTION_FINISH, tweenPosXFinish);
}
Links:
Kirupa: ActionScript 3 Tip of the day Page 9
gskinner: Weakly referenced listeners
[Added Sept 03, 07]
Someone on FlashMedia maillist had this one:
Never Ever Use Tween or URLLoader or Loader or Timer or…