Reducing Memory Usage?

In a mobile game of ours we have introduced the memory usage and texture usage with the collect garbage function and we have displayed the numbers to an updatable text field, we have noticed when we add the objects into the game that this number is going up. but on the removal of these objects the counter isn’t going down.

we use the deletion process of

object:removeSelf()

object = nil

Hi @jazzarssoul,

Your removal process is fine, but most likely you still have references to the objects that are keeping them “locked” in memory. The following guides/tutorials might help you figure this out:

http://docs.coronalabs.com/guide/basics/optimization/index.html

http://www.coronalabs.com/blog/2013/04/02/cleaning-up-display-objects-andlisteners/

Brent

Hey Brent,

I did a quick read through of the guides and can’t narrow out what information is required.
We initialise the enemy arrays with a local property on the outside of creation and have a function that creates them with no local properties that gets run on tap of background.

This is how we create our display objects

– primary key kind of business for each individual object

Local enemy1 = -1
Local newEnemies1 = {}
Function spawn()
newEnemies[enemy1] = display.newimagerect()
– enemy properties etc etc etc
End

Are you thoroughly cleaning out this “newEnemies” table on scene clear, and removing enemies from it when one is removed from the scene? Have you checked and double-checked that when you attempt removal, it’s actually locating that object (ID) within the table and removing it? I’m not sure how you handle your table removal in this case.

Brent

We don’t swap scenes in this game. It’s all happening on the one scene.
And when it comes to removing objects we have a print function before removal and one after.
The start print is like object: 00377bb
And after is nil

Hi @jazzarssoul,

If I inspect your code above, the first thing I notice is that you’ve typed the table names wrong. You have both “newEnemies1” and “newEnemies”. But for the sake of this topic, I’ll assume you meant to use “newEnemies” without the “1” at the end:

[lua]

local enemy1 = -1

local newEnemies = {}

function spawn()

   newEnemies[enemy1] = display.newImageRect( … )

   --enemy properties etc etc etc

end

[/lua]

With that in mind, it appears that you’re effectively doing this:

[lua]

newEnemies[-1] = display.newImageRect( … )

[/lua]

Why are you setting the index to -1? You should probably just insert the objects in progressive order depending on how many items are in the table:

[lua]

newEnemies[#newEnemies+1] = display.newImageRect( … )

[/lua]

Brent

one thing I should of included is this is going to be a game of many objects so we’ve implemented a sort of primary key system where individual arrays are the keys of the newEnemies arrays such as:

[lua]

enemy1 = {} – primary key of enemy1 objects

[/lua]

now when we call the spawn() function:

[lua]

function spawn()

    enemy1 = enemy1 + 1

    newEnemies[enemy1] = display.newImageRect( … )

    – etc etc etc

end

[/lua]

So you’re saying, “enemy1” will be a table of several objects related to enemy1? As in, you might have 5 objects within this table, which is in turn wrapped within “newEnemies”? So, for example (in “tree” notation):

newEnemies

----enemy1

--------oneEnemy

--------otherEnemy

--------anotherEnemy

----enemy2

--------yetAnotherEnemy

--------yetAnotherEnemyAgain

Is this the basic structure?

Brent

I believe I’ve lead a false trail somewhere as I’ve changed between what I had assumed is happening and what is actually happening, I will now try to explain our object creation with 2 separate objects:

[lua]

– primary key index, (-1) easier to increment at the start of creations

e1 = -1  – enemy one

e2 = -1  – enemy two

– the spawns

newEnemy1 = {}

local function spawnOne()

    e1 = e1 + 1

    newEnemy1[e1] = dispaly.newRect( … )

    – etc etc etc

end

newEnemy2 = {}

local function spawnOne()

    e2 = e2 + 1

    newEnemy2[e2] = dispaly.newRect( … )

    – etc etc etc

end

[/lua]

Hi @jazzarssoul,

OK, just to confirm, you will have multiple enemies in the “newEnemy2” table? Such that the table holds a “class” of enemies, and you can add several to it, or remove enemies from it?

–or–

Does “newEnemy2” simply represent just one enemy on the screen?

Do you wrap these “newEnemyX” tables inside another master table like “allEnemies”?

It is the first of those 2 choices you have explained.

In the game there are a few different objects including zombies, tanks and cars. Each of these object types have their own array and creation function.

So there is a zombie array and zombie create function, a tank array and tank create function and so on.

So for each type there is this chunk of code.

[lua]

–zombies, Type of object

z1=-1 --counter

zombies={} --initialise array

function createZombie() --function begins

    z1=z1+1

    zombies[z1]=display.newRect(…)

end

[/lua]

Hi @jazzarssoul,

I mentioned this above, but I’m still confused why you’re setting the counter to -1 as the starting point. I see that this increments before the object is created, thus making your first insertion index 0, but that’s not logical to me. Shouldn’t it start at 0, and then the first zombie will be index 1, and the next index 2, etc.?

it can be swapped around a bit so we can have the counters start at 0, could this be a suspected cause? Or are you trying to get a feel for why we’ve done things the way we have

Yes, I was a little curious about the indexing thing, but let’s get back to the memory cleanup issue. Where and how are you removing these objects from these “holding tables”?

we have a pretty simple shoot function that registers bullets to zombie which goes along the lines of:

[lua]

local function hitTestObjects(obj1, obj2)

  return obj1.contentBounds.xMin < obj2.contentBounds.xMax

  and obj1.contentBounds.xMax > obj2.contentBounds.xMin

  and obj1.contentBounds.yMin < obj2.contentBounds.yMax

  and obj1.contentBounds.yMax > obj2.contentBounds.yMin

end

[/lua]

this helps identify which collision is getting handled or who is in place.

we have a delete function that takes the relative object getting deleted from the returned object above to here:

[lua]

local toRemove={}        

        function killObject()

            for i=1,#toRemove do

                 toRemove[i]:removeSelf()

                 toRemove[i] = nil

            end

        end

        Runtime:addEventListener(“enterFrame”,killObject)

[/lua]

and just from testing this all out we notice memory does not clear. are we missing anything?

I have no idea what has happened to the layout of the lua blocks there… I hope it is legible enough

So, for example, the zombies (IDs) get copied to the “toRemove” table, then those IDs are used to remove the zombies from the screen? Did you ever remove the zombies from the original table? Any place you still have the ID for an object… no matter which table… it will remain locked in Lua memory unless you nil it out. You probably knew this, but just check and confirm that you’re clearing ALL references to an object when you remove it from the display.

Hi @jazzarssoul,

Your removal process is fine, but most likely you still have references to the objects that are keeping them “locked” in memory. The following guides/tutorials might help you figure this out:

http://docs.coronalabs.com/guide/basics/optimization/index.html

http://www.coronalabs.com/blog/2013/04/02/cleaning-up-display-objects-andlisteners/

Brent

Hey Brent,

I did a quick read through of the guides and can’t narrow out what information is required.
We initialise the enemy arrays with a local property on the outside of creation and have a function that creates them with no local properties that gets run on tap of background.

This is how we create our display objects

– primary key kind of business for each individual object

Local enemy1 = -1
Local newEnemies1 = {}
Function spawn()
newEnemies[enemy1] = display.newimagerect()
– enemy properties etc etc etc
End

Are you thoroughly cleaning out this “newEnemies” table on scene clear, and removing enemies from it when one is removed from the scene? Have you checked and double-checked that when you attempt removal, it’s actually locating that object (ID) within the table and removing it? I’m not sure how you handle your table removal in this case.

Brent