When you have memory leaks in your app/game generally there are several common things at fault. These are listed below, you should always adhere to these practices:
- Always ensure to remove all runtime and object listeners before/during changing scenes. If you don’t you will have both memory leaks and odd bugs.
EG
local function imageFunction(event)
return true
end
local function runTimeFunction(event)
return true
end
local myImage = display.newImage("myImage.png")
myImage:addEventListener("touch", imageFunction)
Runtime:addEventListener("enterFrame", runTimeFunction)
--Get rid of them
myImage:removeEventListener("touch", imageFunction)
Runtime:removeEventListener("enterFrame", runTimeFunction)
- Always cancel timers when changing scenes and always as a rule create a variable to store your timer so you can cancel it.
EG:
--Create a forward reference for the timer (also known as "predeclaring"
local myTimer
local function testFunction()
print("Hello")
end
--Create the timer
myTimer = timer.performWithDelay(1000, testFunction)
--get rid of the timer
if myTimer ~= nil then
timer.cancel(myTimer)
end
myTimer = nil
- When removing images be sure also to nil out the reference to the image, if you don’t do this the lua garbage collector won’t class it as garbage and it will remain in memory.
EG:
local myImage = display.newImage("myImage.png")
--Get rid of it
display.remove(myImage)
myImage = nil
- When removing audio, ensure to follow the following steps:
Stop Audio > Dispose of audio > Nil audio handle and sound file reference.
EG:
local myAudioFile = audio.loadSound("mySound.mp3")
local myAudioHandle = audio.play(myAudioFile)
--Get rid of it
audio.stop(myAudioHandle)
audio.dispose(myAudioFIle)
myAudioHandle = nil
myAudioFile = nil
- Always cancel transitions when changing scenes and always as a rule create a variable to store your transition so you can cancel it.
EG:
--Create a forward reference for the transition (also known as "predeclaring"
local myTransition
local myImage = display.newImage("myImage.png")
myImage.alpha = 0
--Create the transition
myTransition = transition.to(myImage, {alpha = 1})
--get rid of the transition
if myTransition ~= nil then
transition.cancel(myTransition)
end
myTransition = nil
- When creating functions to create objects (text, images etc) always make sure you return the object, if you don’t then you have no way of clearing its memory
EG:
local function createBox()
local box = display.newImage("box.png")
return box
end
- When changing text, change the text object directly, don’t keep creating new text objects.
EG:
local function createHighScore()
local highScore = display.newText("high score: 0000", 100, 100, native.systemFont, 24)
return highscore
end
--Create the highscore text object
local highScore = createHighScore()
--Update the score
highscore.text = "high score: 0100"
But wait, I haven’t been doing this and my game is leaking memory between scene changes
Don’t worry, it’s not too late. Here is one way you can work out what part of your code is causing the leak.
-
Code commenting. Start piece by piece commenting out sections of your code. Do this piece by piece though, don’t rush ahead. Comment out say the function that spawns your enemies, start your game change scenes and monitor your memory usage, if it goes down (even by a small bit) you know that in the commented part of your code that you are leaking a bit of memory in there.
-
Comb through all your code files looking for things I mentioned above. It may take time but if you put the effort in you will see results.
How do i print my memory usage? -
If you are using storyboard and have storyboard.isDebug set to true you can use the following command:
storyboard.printMemUsage()
I would recommend placing this in your enterscene function.
- If you are using director, scene manager or are using something you created yourself… you can use the following function:
local function printMemUsage()
local memUsed = (collectGarbage("count")) / 1000
local texUsed = system.getInfo( "textureMemoryUsed" ) / 1000000
print("\n---------MEMORY USAGE INFORMATION---------")
print("System Memory Used:", string.format("%.03f", memUsed), "Mb")
print("Texture Memory Used:", string.format("%.03f", texUsed), "Mb")
print("------------------------------------------\n")
return true
end
--Call it at the beginning of your new scene or the first line under your .new() function
printMemUsage()
Iv’e done all this but I am still leaking memory?
It is nearly impossible to write 100% bug/memory leak free code, it comes hand in hand with the profession. The following are safe regions of memory leaks and are nothing to worry about:
1kb > 8kb
If you are leaking more than that then I would suggest trying the things I have mentioned to get it lower.
You may find that your memory usage climbs for a while then drops off to it’s original usage again, this is the expected behavior and how the lua garbage collector works, it’s memory removal is not always instant, you need to bear that in mind.
Ok I’ve tried everything and I am still leaking more memory than you said should be ok
If you have exhausted every option, tried all my techniques, asked on the forums (etc) and are 100% sure your code shouldn’t be leaking but it is, you have one last alternative. You can avail of our premium support service and one of our trained members of staff will work with you on your code. You can find more info on this here: http://www.anscamobile.com/corona/support/ [import]uid: 84637 topic_id: 26628 reply_id: 326628[/import]