views:

8235

answers:

5

Is it possible to programmatically force a full garbage collection run in ActionScript 3.0?

Let's say I've created a bunch of Display objects with eventListeners and some of the DO's have been removed, some of the eventListeners have been triggered and removed etc... Is there a way to force garbage collection to run and collect everything that is available to be collected?

+10  A: 

Yes, it's possible, but it is generally a bad idea. The GC should have a better idea of when is a good time to run than you should, and except for a very specific case, like you just used 500MB of memory and you need to get it back ASAP, you shouldn't call the GC yourself.

In Flash 10, there is a System.gc() method you can call (but please don't, see above). And in Flash 9, there is an unsupported way to force it via an odd LocalConnection command, but it may not work in all versions. See this post by Grant Skinner.

davr
+4  A: 

For all currently released versions, System.gc() only works in the debug version of the Flash player and ADL (the debug environment for AIR apps). Flash player 10 beta currently does work in all flavors.

I agree with Davr, it's a bad idea to do. The runtime will usually have a better idea than you do.

Plus, the specifics of how the garbage collector works is an implementation detail subject to change between flash player versions. So what works well today has no guarantee to work well in the future.

Marc Hughes
There is a specific case, I have a DataCache class, the way it work is it keeps result object that send out updated events when refreshing/receiving data. The way the cache is cleaned is I just clean all results from it and send the event which causes any remaining listeners to re-request their data. If I can't force all listeners that still dangle waiting for GC to be cleaned up immeadiatly before sending out the refresh event, those dangling listeners will request data again.
FredV
+2  A: 

As others said: do not try to GC manually, there are hacks but it's not safe.

You should try recycling objects when you can - you'll save a lot of memory.

This can be applied for instance to BitmapDatas (clear and reuse), particles (remove from display and reuse).

Philippe
A: 

I have a comment on those saying you should never do GC manually. I'm used to manual memory management in C++ and I prefer sharedptr a lot over GC, but anyway.

There is a specific case where I can't find another solution than do a GC. Please consider: I have a DataCache class, the way it work is it keeps result objects for certain method calls that send out updated events when refreshing/receiving data. The way the cache is refreshed is I just clean all results from it and send the event which causes any remaining listeners to re-request their data and listeners that went out of scope should not rerequest which cleans out not needed results. But apparently, if I can't force all listeners that still dangle waiting for GC to be cleaned up immediatly before sending out the "ask you data again" event, those dangling listeners will request data again unnecessarily. So since I can't removeEventListener because AS3 doesn't have destructors I can't see another easy solution than forcing a GC to make sure there's no dangling listeners anymore.

(Edit) On top of that I cannot use removeEventListener anyway for binding which were setup in mxml, for example (using my custom DataCacher class which handles remoteobj)

<mx:DataGrid id="mygrid" dataProvider="{DataCacher.instance().result('method').data}" ... />

When the popup window containing this datagrid is closed, you would expect the bindings to be destroyed. Apparently they live on and on. Hmm, shouldn't flex destroy all bindings (meaning eventlisteners) from an object when it's being marked for GC because the last reference is deleted. That would kinda solve the problem for me.

At least that's why I think, I'm still a beginner in Flex so any thoughts would be appreciated.

FredV
A: 

If you have to, calling the gargabe collector could be useful... so, you have to be carefull how and when you do it, but there is no doubt that there are times when is neccesary.

for example, if you have an app that is modular, when you change from one view to the other, all the deleted objects could represent a large amount of memory that should be available as faster as possible, you just need to have control of the variables and references you are disposing.

Alexander