Reputation: 6609
I am developing an Android game. As the game progresses it gets steadily slower. I am sure some of the speed changes are due to the higher enemy count and stuff like that, but I am also worried that I may have a memory leak.
The nature of the game is this:
It is a tower defense game built with lists and arrays. All of the tower data is stored in numerous gameBoard arrays. Throughout the drawing and update code every block is evaluated. Most times nothing needs to be done. The game is a 30x14 grid, so 420 locations are evaluated probably 15 times throughout the course of the loop. This isn't great programming, but I assumed the code was simple enough that it would work fine. And most times nothing needs to be done, so I didn't think it would matter.
The enemies, all bullets and various particle effects are all stored and updated in lists like the code seen below. I skinned the game a couple days ago, keeping all of the game logic the same, but adding effects. Adding bitmaps and coloring styles did not change the way the game ran. The slowdown was apparent when I added particle effects like those shown below. They do not cause any slowdown early in the game. Later in the game they do. I assumed that the memory was being managed wrong because of this.
I have a bunch of different classes like this:
public class FadeBlock {
private float x;
private float y;
private float radius;
private int level;
private float startRadius;
private float endRadius;
private float elapsedTime;
private float fadeTime;
private boolean terminate;
private float percent;
public FadeBlock(int Level, float CenterX, float CenterY, float StartRadius, float EndRadius, float FadeTime)
{
x = CenterX;
y = CenterY;
level = Level;
fadeTime = FadeTime;
terminate = false;
percent = 1;
startRadius = StartRadius;
endRadius = EndRadius;
radius = startRadius;
}
public void Update(float ElapsedTime)
{
elapsedTime += ElapsedTime;
percent = (((float) elapsedTime) / ((float)fadeTime));
radius = (endRadius - startRadius)*percent + startRadius;
if (percent >= 1)
{
terminate = true;
}
}
public void Draw(Canvas canvas, Paint paint)
{
if (!terminate)
{
switch (level) {
case 1:
paint.setARGB(255, 61, 190, 255);
break;
case 2:
paint.setARGB(255, 162, 0, 194);
break;
case 3:
paint.setARGB(255, 0, 194, 162);
break;
case 4:
paint.setARGB(255, 129, 194, 0);
break;
case 5:
paint.setARGB(255, 255, 85, 0);
break;
case 6:
paint.setARGB(255, 194, 65, 0);
break;
default:
paint.setARGB(255, 61, 190, 255);
break;
}
paint.setAlpha((int) (255*(1 - percent)));
canvas.drawRect(x-radius, y - radius, x + radius, y + radius, paint);
}
}
public boolean Kill()
{
return terminate;
}
}
That I add to an arrayList like this:
public List<FadeBlock> FadingBlocks = new ArrayList<FadeBlock>();
And manage with the following loops:
for (int i = 0; i < FadingBlocks.size(); i++)
{
FadingBlocks.get(i).Draw(canvas, paint);
}
for (int i = 0; i < FadingBlocks.size(); i++)
{
FadingBlocks.get(i).Update(elapsedTime);
}
for (int i = (FadingBlocks.size() - 1); i > -1 ; i-- )
{
if (FadingBlocks.get(i).Kill())
{
FadingBlocks.remove(i);
}
}
To add items to the list I do something like this:
FadeBlock tempBlock = new FadeBlock(Units.get(i).getLevel(), Units.get(i).getX()+16, Units.get(i).getY()+16, 16, 32, 250)
FadingBlocks.add(tempBlock);
Is that a bad way to manage my objects? Would that cause memory issues over time on an android device?
Upvotes: 0
Views: 1202
Reputation: 10203
It's real hard to know if this or that causes a Memory Leak from a few lines of code. Here are a thought for you :
Use the ObjectPool pattern for your game : you create N enemies while starting your game, some of them inactive. Then when you need a new enemy, instead of creating a new one and adding it to your ArrayList, you take one from the pool which is inactive, and activate it. Samely, instead of deleting an enemy, you just mark it as inactive in the pool.
This can prevent memory overuse, as an ArrayList starts with a capacity of x, and when needed will increase to 2x etc... but it will never release memory when you remove object. Also store you object pool in a static list instead of an array list, as iterations and access to the object will be faster.
Upvotes: 3