Plummeting performance

1MrPaul1

  • *
  • Posts: 1268
I have this problem too.
Placing on scene many actors and have maximum fps 59. But if to kill this actors on scene, fps fast decreasing but loading of memory increasing. For 10 minutes I lost about 25 fps. Why? Scene don't have any actors, i do not create any new actors, but fps decreasing so fast by itself.

captaincomic

  • *
  • Posts: 6109
Create/Kill shouldn't cause a FPS drop, it should always have the same impact on performance. Creating an actor is slow compared to "creating" a recycled actor, but it shouldn't become slower over time.

I went into this assuming the slowdown was not "supposed" to happen, but it definitely does. Any ideas why? It really looks like killed actors are leaving behind ghosts who eat resources.
I don't really have an idea why. According to your numbers the execution time of Create/Kill blocks stays the same over time, while the FPS drop. So maybe it's a memory leak? Maybe the actor is not disposed correctly in the "kill" block?

Create/Recycle is not supposed to be used together, so that's not an issue.

I think this still qualifies as an issue. "Compiles and executes, but utterly cripples your game" is a pretty poor outcome for this scenario. I think we'd be better served by having the game throw an exception or error, rather than happily gobbling cycles and RAM until the game halts, completely.
Yeah, I have to agree. I just meant that the performance of Create/Recycle is not an issue. It's true that it's not good that the combination Create/Recycle is possible and doesn't even generate a warning.

hansbe

  • Posts: 262
Nice discussion going on here, I did some research myself.

The following code will kill performance in your game quite quickly:

Code: [Select]
public var actorArray : Array;

//This is executed every frame of the game
public function update(list:Array):void
{
actorArray.push(createActor(actorType,0,0,FRONT));
actorArray[actorArray.length-1].kill();
}

The reason why this is so bad is that a reference is kept to the actor in actorArray and then the garbage collector won't release it from memory.

This next bit of code is steady, i.e., in 1000s of actors created:

Code: [Select]
public var actorArray : Array;

//This is executed every frame of the game
public function update(list:Array):void
{
actorArray.push(createActor(actorType,0,0,FRONT));
actorArray[actorArray.length-1].kill();
actorArray[actorArray.length-1] = null ;
}

However, the last bit of code causes the allocated memory to bounce up and down by 12 MB per second. Which I tested through:

Code: [Select]
//This is executed every frame of the game
public function update(list:Array):void
{
print(
actorCount +
"min: " + Profiler.minMem +
"max: " + Profiler.maxMem +
"current: " + Profiler.currentMem
);

for (var i=0; i<2; i++){
actorArray.push(createActor(actorType,0,0,FRONT));
actorArray[actorArray.length-1].kill();
actorArray[actorArray.length-1] = null ;
}
actorCount+=2;
}

The constant memory allocation/release is costly for performance, and therefore recycled actors are preferable whenever you can use them.

Whether or not it makes sens to make the engine utilize recycled actors in all cases, i'm not sure. But one thing I see that the engine might improve on is how each time an actor is created, the bitmapdata seems to be copied (the top program stalled my computer in <10 seconds with a 512x512 bitmap, using >500MB of memory). There should be no need to do this copying on every occasion. Instead if custom alteration of bitmap / frame data is used, it seems better to provide a method to initialize this when it is needed. E.g. pixels = pixels.copy();

Another thing I think should be implemented (which I havent seen) is a default destructor method for behaviors (e.g. destroy() or dispose()). This isn't so hard to generate from the attribute lists for design mode, and will help those who write in code mode to clear up after themselves.