memory leak issue - help desperately required by noob

I have an accumulating memory leak problem. I have a zombie game where I’m generating about 200 zombie during a play session. Creating each zombie seems to take 20k hit on the memory.

After the level, I have a ‘purge’ function which deletes all the zombies from memory. But…it seems to only be removing about 3k per zombie. So, obviously, each level played my memory is getting bloated!

my ‘create a zombie’ code is:*****************************************************************

if (zombieType == “normal”) then

     zombie[i] = display.newSprite(normalZombieFrames, normalZombieSequenceData)

     zombie[i]:setSequence(“runRight”)

     zombie[i].health = 50–normalZombieHealth

     zombie[i].meleeDamage = meleeDamageFromZombie

     zombie[i].objType = “normalZombie”

     zombie[i].speed = math.random (6,12)/100–enemyRunSpeed

     zombie[i].xScale=1.25

     zombie[i].yScale=1.25

     zombie[i].shadow = display.newImage(“shadow.png”,0,0)

elseif (zombieType == “fat”) then

     zombie[i] = display.newSprite(fatZombieFrames, fatZombieSequenceData)

     zombie[i].health = fatZombieHealth

     zombie[i].meleeDamage = meleeDamageFromZombie *10

     zombie[i].objType = “fatZombie”

     zombie[i].speed = math.random (2,4)/100–enemyRunSpeed

     zombie[i].shadow = display.newImage(“shadow.png”,0,0)

     zombie[i].shadow.xScale =1.75 

     zombie[i].shadow.yScale =1.75 

elseif (zombieType == “leaper”) then

     zombie[i] = display.newSprite(leaperZombieFrames, leaperZombieSequenceData)

     zombie[i].health = leaperZombieHealth

     zombie[i].meleeDamage = meleeDamageFromZombie *5

     zombie[i].objType = “leaperZombie”

     zombie[i].speed = math.random (12,16)/100–enemyRunSpeed

     zombie[i].xScale=1.3

     zombie[i].yScale=1.3

     zombie[i].shadow = display.newImage(“shadow.png”,0,0)

end --of if zombieType is normal/fat/leaper

zombie[i].myNumber = idNumber

zombie[i].isFixedRotation = true

zombie[i].isHalted = false

zombie[i].isAddedToHaltedZombieTable = false

zombie[i].myBarricadeTarget = 0

zombie[i].myObstacleTarget = 0

zombie[i].isInMeleeWith = 0

zombie[i].isDead = false

zombie[i].playerTargetted = false

zombie[i].tickLast = 0

if (spawnLocation == “right”) then

     zombie[i].x = 3000

     zombie[i].y = math.random(300,2700)

elseif(spawnLocation == “bottom”) then

     zombie[i].x = math.random(0,3000)

     zombie[i].y = 3000

elseif(spawnLocation == “left”) then

     zombie[i].x = 0

     zombie[i].y = math.random(500,2500)

elseif(spawnLocation == “top”) then

     zombie[i].x = math.random(400,3000)

     zombie[i].y = 0

end

local zombieColourR = math.random (80,100)

local zombieColourG = math.random (80,100)

local zombieColourB = math.random (80,100)

zombie[i]:setFillColor(zombieColourR/100,zombieColourG/100, zombieColourB/100)

zombie[i].xOrig = zombie[i].x --used by ‘retreat’ function

zombie[i].yOrig = zombie[i].y

zombie[i].icon = display.newImage(“zombieIcon.png”,zombie[i].x,zombie[i].y)

zombie[i].icon.alpha = 1

zombie[i].shadow.x = zombie[i].x+15

zombie[i].shadow.y = zombie[i].y+15

zombie[i].shadow.alpha=1

zombie[i].tag = display.newText(string.format("%d ",idNumber), zombie[i].x, zombie[i].y+55, nil,30)

zombie[i].tag.alpha = 0

zombie[i].crosshair = display.newImage(“MoveBritCursor.png”,zombie[i].x,zombie[i].y)

zombie[i].crosshair.alpha = 0

local enemyGoalChoice = math.random(1,#enemyGoal) --todo

zombie[i].goalChoice = enemyGoalChoice

zombie[i].facing = (getImageRotation(zombie[i].x,zombie[i].y,enemyGoal[enemyGoalChoice].x,enemyGoal[enemyGoalChoice].y))

physics.addBody(zombie[i], {“dynamic”, density = 1, bounce = 0,radius=32})

zombie[i].isSensor = true

zombie[i].collision = zombieCollision

zombie[i]:addEventListener( “collision”, zombie[i])

local totDist = distanceBetween(zombie[i], enemyGoal[enemyGoalChoice])

local travTime = totDist / zombie[i].speed

transition.to (zombie[i], {time=travTime, x=enemyGoal[enemyGoalChoice].x, y=enemyGoal[enemyGoalChoice].y})

transition.to (zombie[i].shadow, {time=travTime, x=enemyGoal[enemyGoalChoice].x+20, y=enemyGoal[enemyGoalChoice].y+15})

transition.to (zombie[i].tag, {time=travTime, x=enemyGoal[enemyGoalChoice].x, y=enemyGoal[enemyGoalChoice].y})

transition.to (zombie[i].crosshair, {time=travTime, x=enemyGoal[enemyGoalChoice].x, y=enemyGoal[enemyGoalChoice].y})

transition.to (zombie[i].icon, {time=travTime, x=enemyGoal[enemyGoalChoice].x, y=enemyGoal[enemyGoalChoice].y})

zombie[i].currentAction = “run”

zombie[i].animation = (pickAnimation(zombie[i].facing,zombie[i].currentAction))

zombie[i]:setSequence(zombie[i].animation)

zombie[i]:play()

depthGroupPlanning:insert(zombie[i].icon)

zombie[i].icon:toFront()

backGroup:insert(zombie[i].shadow)

depthGroupPlanning:insert(zombie[i].tag)

depthGroup:insert(zombie[i].crosshair)

depthGroup: insert (zombie[i])

zombie[i].tag:toFront()

zombie[i]:addEventListener(“tap”,playerTargetZombie)

my ‘delete a zombie’ code is: ****************************************************************

function deleteEnemyUnit(i)

print (‘deleteEnemyUnit fn called for zombie’,i)

transition.cancel (zombie[i])

transition.cancel(zombie[i].shadow)

transition.cancel (zombie[i].tag)

transition.cancel(zombie[i].crosshair)

transition.cancel (zombie[i].icon)

zombie[i].health = nil

zombie[i].meleeDamage = nil

zombie[i].objType = nil

zombie[i].speed = nil

zombie[i].myNumber = nil

zombie[i].isFixedRotation = nil

zombie[i].isHalted = nil

zombie[i].isAddedToHaltedZombieTable = nil

zombie[i].myBarricadeTarget = nil

zombie[i].myObstacleTarget = nil

zombie[i].isInMeleeWith = nil

zombie[i].isDead = nil

zombie[i].playerTargetted = nil

zombie[i].tickLast = nil

zombie[i].xOrig = nil

zombie[i].yOrig = nil

zombie[i].goalChoice = nil

zombie[i].facing = nil

zombie[i].currentAction = nil

zombie[i].animation = nil

depthGroupPlanning:remove(zombie[i].icon)

backGroup:remove(zombie[i].shadow)

depthGroupPlanning:remove(zombie[i].tag)

depthGroup:remove(zombie[i].crosshair)

depthGroup: remove (zombie[i])

display.remove(zombie[i].tag)

zombie[i].tag = nil

  display.remove(zombie[i].shadow)

  zombie[i].shadow = nil

  display.remove(zombie[i].crosshair)

  zombie[i].crosshair = nil

  display.remove(zombie[i].icon)

  zombie[i].icon = nil

  zombie[i]:removeEventListener( “collision”, zombie[i])

  zombie[i]:removeEventListener(“tap”,playerTargetZombie)

  --physics.removeBody(zombie[i], {“dynamic”, density = 1, bounce = 0,radius=32})

  display.remove(zombie[i])

  zombie[i] = nil

  print (“memory test”)

checkMemory()

end --of deleteEnemyUnit fn

***********************************************************************

clearly I am a noob…and quite probably a moron. Any help, I’d be incredibly grateful for.

best

Alex

Memory management is actually not that hard to do. Just go over your code and check: for every time you create a variable or item, you need to destroy or remove it after you’ve used it.

Take your “constructor” code besides you, and do the opposite to destroy and you should be fine. Typically memory leaks appear when you forget a certain step actually creates a variable or object.

Also, allow Lua to garbageCollect - memory freed up might take a minute to show up.

Memory management is actually not that hard to do. Just go over your code and check: for every time you create a variable or item, you need to destroy or remove it after you’ve used it.

Take your “constructor” code besides you, and do the opposite to destroy and you should be fine. Typically memory leaks appear when you forget a certain step actually creates a variable or object.

Also, allow Lua to garbageCollect - memory freed up might take a minute to show up.