-
Memory leak problem
I'm trying to create a top down shooting game that involves rapidly creating, adding, and removing objects from the stage. I'm having trouble stripping away all of the references to my 'enemy' objects so that they can be properly cleaned up by garbage collection.
As it is, my game will only run for a few seconds before slowing to a standstill. Tracing System.totalMemory indicates a memory leak that I suspect is caused by not removing all references to my objects. Can anyone tell me what I'm missing?
In my game loop, which is an onEnterFrame event, I check to see if my enemy objects can be removed.
Code:
i = enemyarray.length - 1;
while(i > -1){
var currentenemy:Enemy = enemyarray[i];
if(currentenemy.active == false){
//dispose() removes all event listeners and stops the movieclip
currentenemy.dispose();
this.removeChild(currentenemy);
delete(enemyarray[i]);
enemyarray[i] = null;
enemyarray.splice(i,1);
}
if(currentenemy.collisionstate == 2){
if(currentenemy.removedfromcollision == false){
currentenemy.removedfromcollision = true;
collisiongroup.removeItem(currentenemy);
}
}
i--;
}
currentenemy = null;
i=0;
The enemy objects are spawned every second
Code:
public function spawnenemy(e:TimerEvent){
var currentenemy:Enemy;
currentenemy = new Enemy();
this.addChild(currentenemy);
enemyarray.push(currentenemy);
collisiongroup.addItem(currentenemy);
currentenemy = null;
}
The class file for Enemy
Code:
package com.Shooter{
import flash.display.MovieClip;
import flash.events.Event;
public class Enemy extends MovieClip{
public var health:Number;
public var speedx:Number;
public var speedy:Number;
public var power:Number;
public var active:Boolean;
public var collisionstate:int;
public var id:int;
public var removedfromcollision:Boolean;
//collisionstate
//1 = alive
//2 = dying
public function Enemy(){
init();
}
public function init(){
removedfromcollision = false;
id = 2;
speedx = 0;
speedy = 10;
health = 1;
power = 1;
x = Math.random()*400;
y = -40;
collisionstate = 1;
active = true;
stop();
cacheAsBitmap = true;
addEventListener(Event.ENTER_FRAME, run, false, 0, true);
}
public function run(e:Event){
x += speedx;
y += speedy;
if(currentFrame == 10){
active = false;
}
if(y > 600 + 0.5*(height)){
active = false;
}
}
public function collide(pow:Number){
health -= pow;
if(health < 1){
speedy = speedx = 0;
collisionstate = 2;
play();
}
}
public function dispose(){
stop();
removeEventListener(Event.ENTER_FRAME, run, false);
}
}
}
-
You don't need these lines:
Code:
enemyarray[i] = null;
Code:
currentenemy = null;
In the first case, the next line (the splice) removes the reference at enemyarray[i] anyway, so you don't need to set it to null first. In the second case, currentenemy is a local variable so it will fall out of scope when the function is finished.
Neither of those is causing a memory leak, though. I don't see anything here that would, but this isn't your entire code. I don't see anywhere that you're setting the active state of your enemies to false which would trigger removing them. Obviously, if you never remove them you'll continue to hang on to them, using more memory.
I'd strongly suggest using an object pool to reuse your enemy instances. It'll speed things up (instance creation is expensive) and reduce memory usage.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|