Sup again. I'm making a shooting game and I'm not understandig properly the garbage colector. basically I have a Pistol class:
//the Pistol class public class Pistol extends Gun { public function Pistol():void { //add a listener to listen when mouse is pressed Game.main.stage.addEventListener(MouseEvent.MOUSE_DOWN, shoot); }
public function shoot(e:MouseEvent):void { //create a bullet, the arguments are just to shoot the //bullet in the correct direction var bullet:Bullet = new Bullet( (parent.x + this.x) , (parent.y + this.y), this.rotation); //add the bullet to the stage Game.main.addChild(bullet); } }
Every time i shoot, i new bullet object is created and added to stage. When a bullet is created, an ENTER_FRAME event is added to move the bullet:
When the bullet hits an enemy or leaves the stage I have to remove the bullet from the stage and remove the ENTER_FRAME event:
//removing event and the bullet from stage removeEventListener(Event.ENTER_FRAME, eFrame); Game.main.removeChild(this); //
The bullet were added in the Pistol class and, when I shoot again there's no more a variable pointing to the bullet object. Altough, the bullet were added to the stage, so I presume the garbage colector shouldn't act there.
Finally here's my doubt. If I remove the bullet from the stage, and there's no more variables pointing to it, why I still have to remove that ENTER_FRAME event wich is a method of the object itself. Shouldn't the garbage colector acts there? And, if i had to mannualy remove that ENTER_FRAME event, will the garbage colector acts after I do that? Otherwise that object will be still allocating space in memory. Should I have to use the "delete"?
I believe what you are asking is, why does flash not garbage collect event handlers if the object they're pointing to is null? This is because Flash internally will hold a global reference to event handlers by default, which means they will not be eligible for garbage collection. To counter act this, you can set the very last parameter in the addEventListener function is called "useWeakReference" to true where the default value is false. This will tell flash that if the object the listener is attached to is null, then go ahead and garbage collect the event listener as well. This will not happen immediately as the garbage collector pretty much happens whenever it feels like it, hence why calling the removeEventListener manually makes more sense.
Looking at your code, I would think that creating a bullet array that stores all bullets somewhere, and looping through them in a for loop to update their positions in a global ENTER_FRAME handler would get around this issues. Instead of having each bullet with their own ENTER_FRAME, you make a global ENTER_FRAME where each bullet is looped through and updated before being removed eventually. This would eliminate the need to remove each ENTER_FRAME from each bullet. Just a suggestion.
You are correct on both fronts. If an object is still on stage then it is in the display list and therefore won't be released from memory. If the object is removed from the stage and nothing points to it, then it will be released entirely.
Here is an image explaining flash garbage collection more visually: Objects in memory that nothing points to in code will be removed.