views:

10382

answers:

6

I want to delete/force garbage collection on a class instance from inside itself. Obviously, this = null and delete this don't work. Is it any way I can do that, or am I barking up the wrong tree? I'm basically looking for a destructor of some sort..

I have a class instance that attempts to load an XML file, and if the file is not found, I want to destroy the instance, preferably from inside itself. The point is then to do some things in the parent class depending on whether the child instance is null or not.

I've thought of throwing an event to the parent and delete the child from there, but I'd prefer to do that only if there's no other way.

+1  A: 

AS3 doesn't give you any destructors. The best you can do is set all references to null and keep your fingers crossed -- that the GC will notice it and free the memory.

dirkgently
Ok, but how do I set a class instance null from inside itself?
evilpenguin
@evilpenguin, unless you are using a singleton, you don't do it from inside the class itself. You do it from the class that has instantiated that class.
KingNestor
@evilpenguin: As suggested, you have to do it from outside.
dirkgently
+1  A: 
System.gc()
// Forces the garbage collection process.

Reference:

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/System.html

Koistya Navin
quote: For the Flash Player debugger version and AIR applications onlySo it's of little to none use to me.
evilpenguin
A: 

You should have a read about the garbage collection first, Grant.S wrote a good article about this :

http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html

The point is not to set the class itself to null but delete all its references including listeners. Once it's completely orphaned the garbage may pick it up at one point.

Basic example :

// References a newly created sprite
var reference:Sprite = new Sprite();

// Removes the reference, the Sprite is now orphaned and will probably be garbage collected within some seconds.
reference = null;

A good practice is to systematically create a 'destruct' method on all your classes that removes all its internal references, disposes bitmaps, removes event listeners etc. , thereafter you will just have to worry about unlinking the external ones.

If you use FLEX Builder, you can use the profiler in order to visualize the way Flash Player handles all this internally.

Theo.T
+9  A: 

You shouldn't attempt to remove object from itself - it is a bad practice, and in AS3 you can't do it for sure.

Object may be deleted (i.e. garbage collected) only if there are no references left to that object. Since references always get passed by value and object is generally not aware of which references to it exist, you can't delete object from itself. The only useful thing you can do is to create a method which will clean up all resources used by an instance. Such method will serve as a destructor, but you'll have to call it manually. Don't forget that event listeners will also prevent garbage collection unless you remove them.

There is also a difference between delete'ing a property and setting it to null. Effectively delete will remove a property from an instance of dynamic class. Whereas setting property value to null will not remove the property, but erase any reference that was stored there. Therefore both actions will destroy the reference that was stored in some property. Note, that you can't delete an object, only a property.

There are certain hacks that can be used to initiate garbage collection in flash players 9 and older ones. However recently System.gc() call got available, which does the same thing. Note, that you can't really rely on the fact that GC will actually be called. This is up to the flash player.

Returning to your question: throwing event and notifying parent that something went wrong is actually a good idea. You should stick to it. Moreover, it is better if parent will know of such event that way, and not when it will discover that some properties got magically nulled.

P.S.: Reading Grant Skinner articles on memory in flash player is actually a good idea.

dragonfly
"Note, that you can't delete an object, only a property." - I'm not sure what you mean by this. What if my property is an object?
Luke
@Luke: I mean that property of object A may hold a reference to some object B, but `delete A.prop` will only delete that property, along with a reference. I.e. A won't have property `prop` anymore, but there will probably be references to object B left somewhere. So B won't get GC'ed.
dragonfly
`System.gc()` is only available for debug versions of flash player. You should revise to mention that it should not be used for anything other than debugging.
Jonathan Dumaine
@Jonathan Dumaine: thanks for your comment. However I guess that it is clear enought that "you can't really rely" part is implying that System.gc() is of little use in production code. Also if a programmer doesn't attempt to consult with the documentation, resulting problems are completely his fault. +1 to your comment to accent the issue.
dragonfly
+1  A: 

Here is an unsupported way to force garbage collection from GSkinner.

try {
   new LocalConnection().connect('foo');
   new LocalConnection().connect('foo');
} catch (e:*) {}
// the GC will perform a full mark/sweep on the second call.
jedierikb
+2  A: 

If the object was added to a DisplayContainer using the addChild() method, you can remove the object from the container from within the object, by using parent.removeChild(this). If there are no references to the object left after that, it will be picked up by the garbage collector.

The only problem is when you have event listeners within the object, which you can either remove manually or let the garbage collector do it for you by setting weakReference=true on all listeners.

Lankaras Loerepoot