views:

283

answers:

3

Hello!

So I am pretty familiar with memory management in Java, C and C++; however, in flash what constructs are there for memory management? I assume flash has a sort of virtual machine like java, and I have been assuming that things get garbage collected when they are set to null. I am not sure if this is actually the case though. Also is there a way to force garbage collection in Flash? Any other tips?

Thanks

+2  A: 

Flash bytecode is run by the AVM (Actionscript Virtual Machine). In general terms (and without being an expert in Java or the internals of the Flash Player), I think it's safe to say that the AVM model is somewhat analogue to the JVM model (source code is compiled to bytecode, which is run by the VM; in AVM, at least, some of it is interpreted and some is JIT compiled to native code before execution, etc).

AVM is, as you said, garbage collected, so basically memory allocation and deallocation is managed for you by the GC. When an object becomes unreachable, it's eligible for GC (which doesn't mean it is collected right away).

There's a way to force a GC cycle, only available in the debug version of the player, and also a hack, unofficial and undocumented, but you can find some links about it in google (try GC hack flash LocalConnection or something along those lines). Forcing a GC is almost always a bad idea though.

I've recently come across this blog post that explains how the GC works in some deatil, with references to the AVM C++ source code (that part of the player is open source, so you can check it out for more in depth info if you're so inclined). http://jpauclair.net/2009/12/23/tamarin-part-iii-current-garbage-collector-in-flash-10-0/

Juan Pablo Califano
since fp 9.0.115.0 there is no need for the undocumented localconnection garbage colllection hack anymore:http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/system/System.html#gc%28%29 , but only available in the debug player
maxmc
+2  A: 

On a very specific note: memory leaks can become rampant in your code when using EventListeners. The most common example I've seen in AS/Flex tutorials for adding listeners looks like this:

button.addEventListener(MouseEvent.CLICK, doSomething);

This works just fine, but ignores one salient point: the listener is strongly referenced. This means when the component containing this button is GC'd, the listener persists and maintains a reference to the button, meaning it also won't be harvested.

To mitigate this, you can do one of two things:

button.addEventListener(MouseEvent.CLICK, doSomething, false, 0, true);

Here is Adobe's description of the 3 extra fields. Note what they say about strong references:

A strong reference (the default) prevents your listener from being garbage-collected. A weak reference does not.

The other option is to create a destructor in your code so when a component which uses EventListeners removes them before being torn down:

button.removeEventListener(MouseEvent.CLICK, doSomething);
bedwyr
I'd add that removing event listeners should not be considered optional. I do understand the point behind advicing weak listeners, but it tends to encourage sloppiness in a way (that doesn't mean that by using them your code is sloppy, though). Generally, weakref listeners are recommended, "in case you forget to clean up". But in that case, you already have a problem. Considering the life cycle of your objects is quite important. And you should remove listeners when you're done because code will continue to execute otherwise (until the are collected, which is a non deterministic process)
Juan Pablo Califano
@Juan - you make some great points. The fact that listeners persist is a pretty big deal, and not a very obvious problem. Keeping track of your component lifecycle is indeed an important aspect of coding.
bedwyr
On the other hand, adding a listener, even a strong referenced one, doesn't necessarily mean you have a leak. It just means that the dispatcher has a ref to the object that "owns" the handler. If, for instance, the dispatcher is only referenced by the object that owns the handler (because is, say, an instance var, not shared with other objects), as soon as this object (the "owner") becomes eligible for collection, the dispatcher will become unreachable and thus eligible for collection as well.
Juan Pablo Califano
JPC's second comment is extremely important. In the answer above, "This means when the component containing this button is GC'd, the listener persists and maintains a reference to the button, meaning it also won't be harvested." is wrong. If the button is GCed, then the references to the listening function disappear. The problem only occurs when the listener has a shorter lifetime than the thing being listened to, in which case GCing of the listener will be prevented.
Ender
A: 

In addition to what has already been answered it is good idea to use a library like Mr Doob's Actionscript Performance Monitor which will activley display the current memory usuage. Useful for detecting and fixing memory leaks.

Allan