Reputation: 6282
After having some trouble with object deletion, I ran a simple test:
trace("I Exist!")
call to the listened function.This worked as expected - the SWF file did nothing but print "I Exist!" every frame to the console. (In debug mode, of course.)
What I did next did not work as I expected:
I set the only reference of the object to be set to null
on a mouse event, but the messages from the event listener of of said object still appeared in the console after the mouse event was fired and the reference set to null
- meaning the object still existed!
Calling System.gc()
in the document class IMMEDIATELY stopped the event listener from printing further messages and seemingly deleted the item.
From what I understand, calling System.gc()
is discouraged, but as it seems from this simple test the garbage collector is a big FAIL.
Am I doing something wrong here in trying to dispose of the object, or should I simply call System.gc()
every time I want to get rid of an object..?
Edit: Calling System.gc()
with a non-weak listener also results in the object seemingly being removed from memory (?)
Upvotes: 2
Views: 887
Reputation: 3851
Are you sure you removed all references to your object? i.e. did you remove the mouse event listener, if you added the object to the stage, did you removeChild?
Once you're sure all references have been removed, null the object
object = null;
Then importantly call System.gc() TWICE
Garbage collection cal have two phases, Mark and Sweep. Each call of System.gc() only performs one phase.
This is a great article and tool to enable you to track objects in your app to see which objects still have references to them at any point in time.
http://divillysausages.com/blog/tracking_memory_leaks_in_as3
Upvotes: -1
Reputation: 1996
Garbage collection is only triggered by allocation in Flash Player meaning setting an object to null
will not cause the garbage collector to be invoked.
Setting an object to null
only removes a specific reference to that object. In fact, your listener still has a reference to the object, in your case it's a weak reference so when the GC runs the object is collected but until then it's still hanging out in memory -- dispatching and receiving any events you set it up to handle.
The correct way to handle this is to explicitly remove any event listeners you no longer need, then let the GC do its thing when it's good and ready. Typically I handle this by adding a destroy()
method to my classes that allow them to clean up their own mess before I do away with them.
Upvotes: 0
Reputation: 2631
Actually this is the expected behavior of the Flash garbage collection system. The garbage collection routine runs every time System.gc() is called or a new object is created (new keyword). You should allow GC to naturally clean up objects, and anyways System.gc() only works for the debug player and does nothing for the release version.
If you want the listener from firing, it's ALWAYS best to manual remove the listener yourself with removeEventListener. However, if you don't care about the functionality existing until the next collection phase, you can just rely on the weak listener. Hope this helps.
Upvotes: 1
Reputation: 3273
Garbage collection is almost always deferred in modern VMs (Java, Flash Player, .NET, etc.). You can read http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html for more information.
In particular:
In Flash Player 9, the garbage collector's operations are deferred. This is a very important thing to understand. Your objects will not be removed immediately when all active references are deleted. Rather, they will be removed at some indeterminate time in the future (from a developer standpoint). The garbage collector uses a set of heuristics that look at the RAM allocation and the size of the memory stack, among other things, to determine when to run. As a developer, you must accept the fact that you will have no way of knowing when, or even if, your inactive objects will get deallocated. You must also be aware that inactive objects will continue to execute indefinitely, until the garbage collector deallocates them, so your code will keep running (enterFrame events will continue), sounds will keep playing, loads will keep happening, other events will keep firing, and so on.
Upvotes: 3