Help with memory leak

Hi I’m facing a big problem in my game. Ok the problem is memory leak big issue. Ok when I start the game the terminal shows this

MemUsage: 153.095703125
TexMem: 0.002048

Normal then when I play a game is at right here

MemUsage: 192.783203125
TexMem: 1.235968

Then when I quit is at here

MemUsage: 186.517578125
TexMem: 0.002048

Then when I enter the game for the second time is at here

MemUsage: 193.173828125
TexMem: 1.235968

And then when I go back is at here

MemUsage: 188.736328125
TexMem: 0.002048

As you see there is memory leak were I play my game and back to menu and enter the game and leave the game the memory increase everytime I don’t know why I done this

local function change2 () bank:save() Runtime:removeEventListener("enterFrame", wrap) Runtime:removeEventListener("enterFrame", move) Runtime:removeEventListener("enterFrame", moveship) Runtime:removeEventListener("touch",up) Runtime:removeEventListener("touch", down) Runtime:removeEventListener("touch", right) Runtime:removeEventListener("touch", left) Runtime:removeEventListener("touch", stop ) Runtime:removeEventListener( "collision", deadenemy4) Runtime:removeEventListener( "collision", deadenemy3) Runtime:removeEventListener( "collision", deadenemy2) Runtime:removeEventListener( "collision", deadenemy1) Runtime:removeEventListener( "collision", deadenemy) Runtime:removeEventListener( "collision", deadbull) Runtime:removeEventListener( "collision", deadbull2) Runtime:removeEventListener( "collision", bulletdead6) Runtime:removeEventListener( "collision", bulletdead5) Runtime:removeEventListener( "collision", bulletdead4) Runtime:removeEventListener( "collision", bulletdead3) Runtime:removeEventListener( "collision", bulletdead2) Runtime:removeEventListener( "collision", bulletdead) timer.cancel (timer1) director:changeScene("menus") end box:addEventListener("tap", change2)

Still memory leak I even did nil value when the item is removed and still. Please anyone help my memory leak I don’t know what is causing it

[import]uid: 17058 topic_id: 22119 reply_id: 322119[/import]

You have a lot of Runtime listeners there…

I would think a code re-order would fix the problem. One main collision function and one main logic function.

Two event listeners.

I’m not saying that is the reason but i would seriously consider a revamp [import]uid: 84637 topic_id: 22119 reply_id: 87910[/import]

@Danny you think doing that would Improve the memory leak editing my code [import]uid: 17058 topic_id: 22119 reply_id: 87912[/import]

I do.

It sounds like you have a lot going on. In an ideal situation you would only want 1 runtimelistener per type and reference your objects using a name system.

Ie

object.myName = “Stone”

or whatever
[import]uid: 84637 topic_id: 22119 reply_id: 87915[/import]

@Danny still editing my code I still get memory leak what could be the problem [import]uid: 17058 topic_id: 22119 reply_id: 87919[/import]

Maybe post up some code? Maybe you didn’t understand what I meant properly. It would be hard to implement my suggestion that quickly [import]uid: 84637 topic_id: 22119 reply_id: 87922[/import]

@Danny ok. Here is the code were is causing my memory leak the game

[code]module(…, package.seeall)

– Main function - MUST return a display.newGroup()
function new()
local localGroup = display.newGroup()

local physics = require (“physics”)
physics.start()
–physics.setDrawMode(“hybrid”)
physics.setGravity(0,0)
require( “ice” )
local ui = require(“ui”)

local function powertwin ()
twinb = loadFile (“twinb.txt”)
if twinb == “empty” then
twinb = 1
saveFile(“twinb.txt”, twinb)
end
end
powertwin()

local dis = 0
local Life = 100
local kil = 0
local amount = 0
great = false

local bank = ice:loadBox( “bank” )
local bankText = bank:retrieve(“total”)

local bk = display.newImageRect(“bk.png”, 480, 320)
bk.x = 240
bk.y = 160
localGroup:insert(bk)

local distance = display.newText(“m:0”, 30, 10,“Arial”, 18)
localGroup:insert(distance)
local health = display.newText(“Health: 100”, 10, 40,“Arial”, 18)
localGroup:insert(health)

local highText = display.newText("", 0,0,“Arial”,22)
highText.x = display.contentWidth/2
highText.y = 160
localGroup:insert(highText)

local baseline = 315

local sky1 = display.newImage (“road.png”)
sky1:setReferencePoint(display.CenterLeftReferencePoint)
sky1.x = 0
sky1.y = baseline - 20
localGroup:insert(sky1)

local sky2 = display.newImage (“road.png”)
sky2:setReferencePoint(display.CenterLeftReferencePoint)
sky2.x = 480
sky2.y = baseline - 20
localGroup:insert(sky2)

local sky3 = display.newImage (“broken city.png”)
sky3:setReferencePoint(display.CenterLeftReferencePoint)
sky3.x = 90
sky3.y = baseline - 100
localGroup:insert(sky3)

local sky4 = display.newImage (“broken city.png”)
sky4:setReferencePoint(display.CenterLeftReferencePoint)
sky4.x = 480
sky4.y = baseline - 100
localGroup:insert(sky4)

local sky5 = display.newImage (“broken city.png”)
sky5:setReferencePoint(display.CenterLeftReferencePoint)
sky5.x = -70
sky5.y = baseline - 100
localGroup:insert(sky5)

local tPrevious = system.getTimer()
local function move(event)
local tDelta = event.time - tPrevious
tPrevious = event.time

local xOffset = ( 0.1 * tDelta )

sky1.x = sky1.x - xOffset
sky2.x = sky2.x - xOffset
sky3.x = sky3.x - xOffset
sky4.x = sky4.x - xOffset
sky5.x = sky5.x - xOffset

if (sky1.x + sky1.contentWidth) < 0 then
sky1:translate( 480 * 2, 0)
end
if (sky2.x + sky2.contentWidth) < 0 then
sky2:translate( 480 * 2, 0)
end
if (sky3.x + sky3.contentWidth) < 0 then
sky3:translate( 480 * 2, 0)
end
if (sky4.x + sky4.contentWidth) < 0 then
sky4:translate( 480 * 2, 0)
end
if (sky5.x + sky5.contentWidth) < 0 then
sky5:translate( 480 * 2, 0)
end
end

Runtime:addEventListener( “enterFrame”, move )

local box = display.newRect(30, 30, 30, 30)
localGroup:insert(box)

local heli = display.newImageRect(“helicopter.png”,120, 80 )
heli.x = 50
heli.y = 100
heli.hit = “heli”
localGroup:insert(heli)
physics.addBody(heli,{bounce = 0, radius = 20})

local wall = display.newRect(-10, 0, 10, 320)
wall.hit = “wall”
localGroup:insert(wall)
physics.addBody(wall ,“static”)

local wall2 = display.newRect(300, 0, 10, 320)
wall2.hit = “wall2”
localGroup:insert(wall2)
physics.addBody(wall2 ,“static”)

local left = display.newRect(30, 220, 30, 30)
localGroup:insert(left)
local right = display.newRect(100, 220, 30, 30)
localGroup:insert(right)
local down = display.newRect(65, 260, 30, 30)
localGroup:insert(down)
local up = display.newRect(65, 180, 30, 30)
localGroup:insert(up)

local function shoot (event)
if event.phase == “release” then
if tonumber(twinb) == 2 then
local bullet = display.newImageRect(“bullet.png”, 10, 10)
bullet.x = heli.x + 40
bullet.y = heli.y
bullet.hit = “bullet”
bullet.isFixedRotation = true
transition.to (bullet, {time = 2000, x=550})
physics.addBody (bullet, {bounce=0.6})
localGroup:insert(bullet)

local function bulletdead (event)
if event.phase == “began” and event.other.hit ~= “heli” then
display.remove(bullet)
display.remove(twin)
end
end
bullet.preCollision = onLocalPreCollision
bullet:addEventListener( “collision”, bulletdead)

elseif tonumber(twinb) == 1 then
local twin = display.newImageRect(“bullet.png”, 10, 10)
twin.x = heli.x + 40
twin.y = heli.y
twin.hit = “twin”
twin.isFixedRotation = true
transition.to (twin, {time = 2000, x=550})
physics.addBody (twin, {bounce=0.6})
localGroup:insert(twin)
local twin2 = display.newImageRect(“bullet.png”, 10, 10)
twin2.x = heli.x + 40
twin2.y = heli.y + 15
twin2.hit = “twin”
twin2.isFixedRotation = true
transition.to (twin2, {time = 2000, x=550})
physics.addBody (twin2, {bounce=0.6})
localGroup:insert(twin2)

local function bulletdead6 (event)
if event.phase == “began” and event.other.hit ~= “heli” then
display.remove(twin2)
display.remove(twin)
end
end
twin2.preCollision = onLocalPreCollision
twin2:addEventListener( “collision”, bulletdead6)

end
end
end

ButtonA = ui.newButton{
default = “buttonoverA.png”,
over = “buttonA.png”,
x = 360,
y = 280,
onEvent = shoot,
}
localGroup:insert(ButtonA)

local function enemies (event)
local enem1 = display.newRect(0, 0, 40, 40)
enem1.y = math.random(40, 280)
enem1.x = 500
enem1.isFixedRotation = true
transition.to (enem1, {time = 5000, x=-50})
physics.addBody (enem1, {bounce=0.6})
enem1.hit = “enem1”
enem1.hits = 0
localGroup:insert(enem1)
local function deadenemy3 (event)

if event.phase == “began” and event.other.hit == “twin” then
enem1.hits = enem1.hits + 1
if enem1.hits > 2 then
amount = 1
bank:increment( “total”, amount )
display.remove(enem1)
enem1 = nil
end
end
end
enem1.preCollision = onLocalPreCollision
enem1:addEventListener( “collision”, deadenemy3)

local function deadenemy2 (event)
if event.phase == “began” and event.other.hit == “bullet” then
enem1.hits = enem1.hits + 1
if enem1.hits > 2 then
amount = 1
bank:save()
bank:increment( “total”, amount )
display.remove(enem1)
enem1 = nil
end
end
end
enem1.preCollision = onLocalPreCollision
enem1:addEventListener( “collision”, deadenemy2)

local function deadenemy (event)
if event.phase == “began” and event.other.hit == “wall” then
display.remove(enem1)
end
end
enem1.preCollision = onLocalPreCollision
enem1:addEventListener( “collision”, deadenemy)

local function deadenemy1 (event)
if event.phase == “began” and event.other.hit == “heli” then
display.remove(enem1)
Life = Life - 1
health.text = “Health:”… Life
enem1 = nil
end
end
enem1.preCollision = onLocalPreCollision
enem1:addEventListener( “collision”, deadenemy1)
local badbull = display.newRect(0,0, 20, 20)
badbull.x = enem1.x - 30
badbull.y = enem1.y
badbull.isFixedRotation = true
transition.to (badbull, {time = 3000, x=-50})
physics.addBody (badbull, {bounce=0.6})
localGroup:insert(badbull)
badbull.hit = “badbull”

local function deadbull (event)
if event.phase == “began” and event.other.hit == “wall” then
display.remove(badbull)
badbull = nil
end
end
badbull.preCollision = onLocalPreCollision
badbull:addEventListener( “collision”, deadbull)

local function deadbull2 (event)
if event.phase == “began” and event.other.hit == “heli” then
display.remove(badbull)
Life = Life -1
health.text = “Health:”… Life
badbull = nil
end
end
badbull.preCollision = onLocalPreCollision
badbull:addEventListener( “collision”, deadbull2)

end
timer1 = timer.performWithDelay(2000, enemies, -1)
local motionx = 0 --X Motion
local motiony = 0 – Y Motion
local speed = 5 – Speed

local function stop (event)
if “ended” == event.phase then

motionx = 0
motiony = 0
end
end

Runtime:addEventListener(“touch”, stop )

local function moveship (event)
heli.x = heli.x + motionx
heli.y = heli.y + motiony
end
Runtime:addEventListener(“enterFrame”, moveship)

function up:touch()
motionx = 0
motiony = -speed
end
up:addEventListener(“touch”, up)

function down:touch()
motionx = 0
motiony = speed
end
down:addEventListener(“touch”, down)

function left:touch()
motionx = -speed
motiony = 0
end
left:addEventListener(“touch”,left)

function right:touch()
motionx = speed
motiony = 0
end
right:addEventListener(“touch”,right)

– The above adds functions and listeners to each bullet and to the ship


local function wrap (event)

if heli.x < -50 then
heli.x = -50
end

if heli.x > 485 then
heli.x = 485
end

if heli.y > 280 then
heli.y = 280
end

if heli.y < 10 then
heli.y = 10
end

if speed < 0 then
speed = 0
end
end
Runtime:addEventListener(“enterFrame”, wrap)

function endGame( )
bank:save()
highText.text = “$” … bank:retrieve( “total” )
end

Runtime:addEventListener(“tap”, endGame )

local function change2 ()
bank:save()
Runtime:removeEventListener(“enterFrame”, wrap)
Runtime:removeEventListener(“enterFrame”, move)
Runtime:removeEventListener(“enterFrame”, moveship)
Runtime:removeEventListener(“touch”,up)
Runtime:removeEventListener(“touch”, down)
Runtime:removeEventListener(“touch”, right)
Runtime:removeEventListener(“touch”, left)
Runtime:removeEventListener(“touch”, stop )
Runtime:removeEventListener( “collision”, deadenemy3)
Runtime:removeEventListener( “collision”, deadenemy2)
Runtime:removeEventListener( “collision”, deadenemy1)
Runtime:removeEventListener( “collision”, deadenemy)
Runtime:removeEventListener( “collision”, deadbull)
Runtime:removeEventListener( “collision”, deadbull2)
Runtime:removeEventListener( “collision”, bulletdead6)
Runtime:removeEventListener( “collision”, bulletdead)
timer.cancel (timer1)
director:changeScene(“menus”)
end
box:addEventListener(“tap”, change2)

return localGroup
end [/code]

This the whole code for the game [import]uid: 17058 topic_id: 22119 reply_id: 87927[/import]

I agree with Danny and that’s the way I write my code. I wouldn’t probably wouldn’t use module() either because it has been deprecated for Lua 5.2 because of memory leaks. Just my two cents :wink: [import]uid: 38820 topic_id: 22119 reply_id: 88036[/import]

@glennbjr then what should I use instead of module? [import]uid: 17058 topic_id: 22119 reply_id: 88089[/import]

That’s the problem using Director and module(…, package.seeall) can cause very small memory leaks. That’s why I switched to using Storyboard instead. I don’t know about the latest version of Director…

http://developer.anscamobile.com/forums/director-class

[import]uid: 38820 topic_id: 22119 reply_id: 88092[/import]

Hello Sebitttas,

Can you post up a .zip file with your project (including all the images) so we can run our memory leak profiler tool on it? It should be able to detect which variable is causing the leak.

Regards,
M.Y. Developers [import]uid: 55057 topic_id: 22119 reply_id: 88170[/import]

@M.Y. Developer how do I post a zip file up [import]uid: 17058 topic_id: 22119 reply_id: 88177[/import]

@M.Y. Developer download it from the zip file here http://tinylemongames.yolasite.com/twitter-news.php [import]uid: 17058 topic_id: 22119 reply_id: 88184[/import]

Hi Sebitttas,

Thanks for the info. We will look at it and let you know.

-M.Y. Developers [import]uid: 55057 topic_id: 22119 reply_id: 88214[/import]

@M.Y. Developers thanks glad you can help also in the first screen you will three boxes

the corner one is to change scene

the one in the left side of the number is to have to change the bullet for the next scene

and the below box is to also change the bullets to twin bullets for the next scene [import]uid: 17058 topic_id: 22119 reply_id: 88216[/import]

Hi Sebitttas,

Thank you for the information. We will keep you updated on what we find.

-M.Y. Developers [import]uid: 55057 topic_id: 22119 reply_id: 88243[/import]

@M.Y. Developers

When your done can you send me my fixed project to my email

sebitttas[at]gmail[dot]com

Thanks [import]uid: 17058 topic_id: 22119 reply_id: 88246[/import]

Hello Sebittas,
Here is what the report looks like generated with Corona Profiler:
http://www.mydevelopersgames.com/site/

-------------------------diff snapshot “57”-----------------------
size increase var name defined in
7 self function Ice:getBox( name ) in ice.lua
7 self function Ice:newBox( name ) in ice.lua
7 self function Ice:destroyBox( name ) in ice.lua
7 self function Ice:loadBox( name ) in ice.lua

Seems like the Ice module is increasing steadily every time you enter the menu. We do not use Ice so we don’t know where to go from there but do you perhaps keep adding keys to Ice? Perhaps you can get away saving your variables in a file using json to serialize/unserialize your lua tables. This is how we implemented it:

--GameState.lua  
--Author: M.Y. Developers  
--License GPL, free for commercial and noncommercial use  
--usage:  
--mySavedTable = require("GameState")  
--mySavedTable.someValue = 1 --this will be saved upon program close.  
--YOU MUST SET DEFAULT VALUES BELOW   
local json = require "json"  
  
local State = {}  
  
local path = system.pathForFile( "GameState.txt", system.DocumentsDirectory )  
local file = io.open( path, "r" )  
if file then  
 -- read all contents of file into a string   
 local contents = file:read( "\*a" )   
 State = json.decode(contents);  
 io.close( file )   
else  
 --SET DEFAULT VALUES HERE  
 State.someDefaultValue = "Anything, can be tables too"  
end   
local function SaveState(event)  
 if( event==nil or event.type ~= "applicationStart" ) then  
 local path = system.pathForFile( "GameState.txt", system.DocumentsDirectory )  
 local file = io.open( path, "w" )   
 if file then  
 file:write( json.encode(State) )   
 io.close( file )  
 end   
 end  
end  
Runtime:addEventListener( "system", SaveState );  
return State  

gameState is a regular lua table except that its contents get saved to a file upon application exit and loads the previously saved values upon application start. Also, on first application start the default values are set.

Thanks,
M.Y. Developers
[import]uid: 55057 topic_id: 22119 reply_id: 88250[/import]

@M.Y. Developers But I want the my save stuff to transfer from one screen to another. You saw what I have is a money system were the money is loaded in one seen then retrieve in another seen but is still the same. What I’m trying to do is have a bank for the player to have when they kill enemies they earn money which they can you towards upgrades. That is why I use Ice, but since that causes a memory leak how can I do that without ice? [import]uid: 17058 topic_id: 22119 reply_id: 88253[/import]

you can make GameState a global variable so it is accessed from all parts of your program. you can do something like this

--in your main.lua  
gameState = require("GameState")  

now you can just add whatever you want to this lua table from any module in your game.

gameState.money = 100  

now every time you close and reopen your program it will save/load the table.

Hope that is clear,
M.Y. Developers [import]uid: 55057 topic_id: 22119 reply_id: 88255[/import]