了解ActionScript的垃圾回收集机制
http://www.davidpett.com/actionscript-3-managing-memory/
I have been doing a lot of work in trying to minimize memory and file size in my flash/actionscript projects, because of the structure of actionscript 3 most of this is a manual process. One of the first things you can do is when adding an event listener, use the optional parameters:
_btn.addEventListener(MouseEvent.CLICK, btnClick, false, 0, true);
The last optional parameter in the addEventListener function is useWeakReference, which by default is set to false, according to the ActionScript 3.0 Documentation, this parameter “Determines whether the reference to the listener is strong or weak. A strong reference (the default) prevents your listener from being garbage-collected. A weak reference does not.”
Another standard that I have imemented is to use the REMOVED_FROM_STAGE event in every class that I write. In this class I remove any display objects that I have added and remove all event listeners that those display objects have, because just removing an object does not do this and hose event listeners will still be there takin up memory and can hinder performance.
package
{
import flash.display.*;
import flash.events.*;
public class MyClass extends Sprite
{
private var _btn:Sprite;
//———————————–
// CONSTRUCTOR
//———————————–
public function MyClass():void
{
addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
}
//———————————–
// INIT
//———————————–
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
addEventListener(Event.REMOVED_FROM_STAGE, dispose, false, 0, true);
_btn = new Sprite();
_btn.addEventListener(MouseEvent.MOUSE_OVER, btnOver, false, 0, true);
_btn.addEventListener(MouseEvent.MOUSE_OUT, btnOut, false, 0, true);
_btn.addEventListener(MouseEvent.CLICK, btnClick, false, 0, true);
_btn.buttonMode = true;
addChild(_btn);
}
//———————————–
// DISPOSE
//———————————–
private function dispose(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
removeEventListener(Event.REMOVED_FROM_STAGE, dispose);
if(_btn)
{
_btn.removeEventListener(MouseEvent.MOUSE_OVER, btnOver);
_btn.removeEventListener(MouseEvent.MOUSE_OUT, btnOut);
_btn.removeEventListener(MouseEvent.CLICK, btnClick);
try
{
removeChild(_btn);
}
catch(e:Error){trace("error: MyClass: dispose: removeChild(_btn): " + e)}
_btn = null;
}
}
}
}
http://dispatchevent.org/mims/creating-weak-references-in-as3/
For those of you not familiar with the concept, a weak-reference is a reference to an object that will not hold the linked object in memory when that object is garbage collected.
There are only two ways to create a weak reference in AS3. The first is with the IEventDispatcher.addEventListener() method which allows you to create a weak link between the dispatcher and the listener. To quote the AS3 Bible:
ActionScript 3.0 introduces the concept of weak and strong memory references. Normally, an object will be garbage collected if there are no references to the object. That is, when no objects are using a variable, it gets thrown out. Weak references allow you to reference an object but the object will still be eligible for garbage collection unless another object holds a strong reference to the object. By setting the [
addEventListener()method's]useWeakReferenceflag to true, you will create a weak link between the event broadcaster and the event listener. That way, if an dispatcher is deleted while there are still listeners attached, the weak reference will allow it to be garbage collected. This helps to prevent memory leaks.
The other way is with the objects used as keys in a Dictionary object.
ActionScript, unlike many other languages, does not have a way to explicitly remove an object from memory. Instead it waits until all references to an object are removed and then auto-deletes it. Therefore, an object will continue to stay in memory if all strong references aren’t removed.
Below is an example of how strong-references hold an object in memory. If you’d like to try this out, copy the below text into a file called StrongReferencesExample.as
package {
import flash.display.Sprite; public class StrongReferencesExample extends Sprite {
public function StrongReferencesExample() {
// create a new object called dog. Add it to the first leash object
// and make leash2 a copy of leash 1.
var leash1:Object = new Dog();
var leash2:Object = leash1; // tracing both leashes will show that they hold a reference to the Dog
trace(leash1); // [object Dog]
trace(leash2); // [object Dog] // deleting the dog from the first leash will not remove it from the second leash
// even though we originally set leash2 equal to leash1
leash1 = null;
trace(leash1); // null
trace(leash2); // [object Dog] // The object (dog) will not be free until all of the references to it (leashes) are broken.
leash2 = null;
trace(leash1); // null
trace(leash2); // null
}
}
}
// Define a simple Dog class within the same file.
class Dog {}
Richard Lord over at Big Room Games has an interesting article on hacking AS3 to allow you to create weak-references to objects. The hack is pretty decent but lacks a few things I’d like to see like strong typing at compile-time or a more refined ‘memory manager’ type functionality. However, I tried implementing both of these and came up empty handed. If you can think of a way to make this strong-typed, I’ll give you a candy bar.
Using the WeakReference hack could be useful if you want to make sure that an object will not stay in memory if you forget to delete all references to it. However, keeping track of your objects and practicing good memory management is a much better solution and hacks like this one should be saved for special cases where tracking use of an object becomes difficult or impractical.
Thanks to Alex for the link!
