2007年5月20日星期日

Garbage Collection: Reference Counting & Mark and Sweep

Garbage collection (GC) is the automatic process in Flash that removes variables from memory when they are no longer needed. There are two processes that handle garbage collection in Flash, reference counting, and mark and sweep.

Reference counting is a process that keeps track of all the variables referencing an object in memory. When a new reference is created to point to an object, its reference count is updated and incremented by one.

ActionScript Code:

var a:Object = new Object(); // new Object in memory given reference count of 1
var b:
Object = a; // Object now has reference count of 2


When ever there are no longer any references pointing to an object in memory, that object is purged from memory and permanently forgotten by the player.

ActionScript Code:

delete a; // Object has reference count of 1
delete b; // Object has reference count of 0, removed from memory


Note: remember, the delete operator only removes variable association, it does not delete objects in memory, the GC is responsible for that. Also delete will only work on non class member variables.

There are certain times when reference counting does not work. For example, if you have two objects that reference themselves but reference nothing else, they remain to have a reference count greater than 0 but they are in no way accessible to you, the programmer, so are in all other means as good as gone.

ActionScript Code:

var a:Object = new Object(); // reference(a) count 1
var b:
Object = new Object(); // reference(b) count 1
a.
b = b; // reference(b) count 2
b.
a = a; // reference(a) count 2
delete a; // reference(a) count 1
delete b; // reference(b) count 1


Here both a and b are removed from the current scope so are no longer accessible. b is accessible from a and a is accessible from b, but since you can never get to a or b there's no way to get to b or a. These objects are as good as deleted from the programmer, however, they will remain in memory because they still contain a reference count greater than 0. This is where mark and sweep comes into play.

Mark and sweep is a process that scans all references and object from a base location (such as the root or stage scope) and marks each one found. All of those not found are inaccessible and are therefore deleted. Given the example with a and b, since a and b are no longer accessible from any object path derived from root, they are not marked and eventually get garbage collected.

Code:

[root] <- scan...

[objectRef (marked)] <- scan...

[objectRef (marked)] <- scan...

[objectRef (marked)] <- scan...

[objectRef (marked)] <- scan...

[objectRef (marked)] <- scan...

...

[delete all objects not marked]

Mark and sweep is a more expensive process compared to reference counting so it takes longer and is performed less often. In fact, provided little or no activity in your movie, many frames could elapse before mark and sweep kicks in. What this means is that you could potentially have variables in memory for a long time after you assumed them to be gone. For objects that have actions associated with them, such as events coming off of enterFrame events, this could be something to be concerned about since those events could still operate after the object should technically be deleted. You should always make sure you "cleanup" your events for situations where they might remain in memory longer than you want.

0 评论: