[Guide] Finding/Solving Memory Leaks

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:

  1. 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)  
  1. 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  
  1. 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  
  1. 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  
  1. 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  
  1. 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  
  1. 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.

  1. 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.

  2. 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?

  3. 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.

  1. 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]

1 Like

Thank you, Danny, for this post. It’s super helpful.

By the way, you noted 1kb > 8kb is safe enough for memory leak. I’m wondering what you mean? Did you mean anywhere between 1kb and 8kb leakage should be tolerable?

Naomi [import]uid: 67217 topic_id: 26628 reply_id: 107910[/import]

Yes anywhere from 1kb>8kb is nothing to be concerned about. If you go nuts like I did on my personal project, you can get it lower. Currently my own game leaks 1kb of memory and gains that 1kb back after a few scene changes. So basically I am leaking 1kb every 3>4 scene changes. [import]uid: 84637 topic_id: 26628 reply_id: 107915[/import]

I’ve read all over the forum that when you remove the object it’s EventLstener also get’s removed so is this not the case?

[lua]local button = newImage(“button.png”)

local function Do Something()
–doing stuff
end

button:addEventListener(“touch”, DoSomething)

button:removeSelf();
button = nil;[/lua]

In an example like this do I still need to remove it manually? Typing this next piece?

[lua]button:removeEventListener(“touch”, DoSomething)[/lua] [import]uid: 123298 topic_id: 26628 reply_id: 109296[/import]

Guys my multiscreen app doesn’t seem to be leaking any memory between scenes (its under 2kb) but during gameplay the memory usage slowly crawls up to around 500 and only then gets collected by the garbage collector and this causes stutter on actual android devices. is this normal for lua memory to grow during gameplay? Note: I’m not spawning, adding event listeners or anything of that sort.

Even in this very simple code lua memory slowly rises…
http://codeviewer.org/view/code:27df [import]uid: 118482 topic_id: 26628 reply_id: 114882[/import]

Hi Danny very useful post , helps new guys like me .

i have one doubt, if i use a display object to insert all my display items. is

disp_group:removeSelf()
disp_group=nil

enough or should i individually remove images like

display.remove(myImage)
myImage = nil

[import]uid: 115284 topic_id: 26628 reply_id: 115010[/import]

Hey great post but just a little typo

[lua]local memUsed = (collectGarbage(“count”)) / 1000[/lua]

“collectGarbage” needs a lowercase g for Garbage

so will be:
[lua]local memUsed = (collectgarbage(“count”)) / 1000[/lua] [import]uid: 26289 topic_id: 26628 reply_id: 115576[/import]

Great post Danny! Thanks you for that. I am wondering about one thing: using Director, do I really need to remove images (inserted into groups) since I was in the impression that Director would do that for me when changing scene? Am I wrong to think that?

Mo [import]uid: 100814 topic_id: 26628 reply_id: 117074[/import]

@lairdGames, I haven’t used director in over a year so I am unsure of it’s current features. I’m sure if you posted that question in the director forums, you would get a proper answer however :slight_smile:

[import]uid: 84637 topic_id: 26628 reply_id: 117105[/import]

Thanks Danny, I will. I am using the Modify version 1.2 (short 15 lines code one)

Mo. [import]uid: 100814 topic_id: 26628 reply_id: 117125[/import]

thanks for this post, i just needed this!

if i manage my transitions from an external module and not the storyboard scene, should i also cancel them between scene changes?? [import]uid: 105206 topic_id: 26628 reply_id: 118021[/import]

About 6)

What if I do something like :

local mytable={}  
local function createBox()  
 mytable.box = display.newImage("box.png")  
end  

Is it ok ? [import]uid: 9328 topic_id: 26628 reply_id: 124924[/import]

I’ve read all over the forum that when you remove the object it’s EventLstener also get’s removed so is this not the case?

local button = newImage("button.png")  
   
local function Do Something()  
--doing stuff  
end  
   
button:addEventListener("touch", DoSomething)  
   
button:removeSelf();  
button = nil;  

In an example like this do I still need to remove it manually? Typing this next piece?

button:removeEventListener("touch", DoSomething)  
  

I also want to get an answer to this question! [import]uid: 199163 topic_id: 26628 reply_id: 134014[/import]

@DPN Sweden,

When you remove an object any event listeners attached to it also get removed.
calling the following is enough

button:removeSelf() -- or display.remove( button ) button = nil [import]uid: 84637 topic_id: 26628 reply_id: 134018[/import]

Hi Danny
Okay thanks!

I am increasing my total memory use when I implement this, but the leakage remains constant. It would seem that Directors clean function takes care of my display objects like someone suspected. Time to look at media events instead.

[import]uid: 199163 topic_id: 26628 reply_id: 134022[/import]

Hi Noobie here,

So i am using Storyboard for my project.
I started testing memory by using the memusage function i found on the forums and it worked for me put it my main.lua file -
only thing it gives me the results every microsecond - thus spamming my terminal and as a result i can not see other print details which would help me progress through the test game procedure.

I want to try the storyboard.printMemUsage() - but can’t get it to work - could someone provide an example of code format-
what goes in the Main.lua and what exactly you put on the scene.lua pages( is it need on all pages or just main?? - it’s probably something simple but i’m missing it!

thanks
T
[import]uid: 199068 topic_id: 26628 reply_id: 139684[/import]

When using “storyboard.printMemUsage()” I am maintaining approximately the same system & texture memory on the enterscene where I placed this. Is this memory accumulating or does it clear every time the scene gets purged?

---------MEMORY USAGE INFORMATION---------
System Memory Used: 1.627 Mb
Texture Memory Used: 40.177 Mb

Also, is the above a safe amount. My app is crashing at the same point in this scene on the iPad 1.

Also, I am inserting all display objects into the group. Do I manually have to remove & nil them or do they automatically get removed and nilled when the scene is purged?

Thanks. [import]uid: 8780 topic_id: 26628 reply_id: 139979[/import]

Hi staytoooned -
Thats a good question - so me +1
This thread is about memory leaks - and it states between 1 to 8 above -but thats a change in memory - what is a good target to keep Sys memory /Tex memory under - and are there device differences?

I got the storyboard.printMemUsage working (on each scene page) and combined it with the purge on scene change.

storyboard.purgeOnSceneChange = true

this produces what i think is the total memory used to create the scene, and because the scene is purged when changed believe this to be the total Mem Used by my app at that point in time.

What i did notice is with Universal building - as i changed the Simulator between IPad and iPhone the Texture memory certainly grew!

This i put down to the graphics (@4x) etc… but it would be handy to know Memory targets that are safe to be under for each device if possible?
T

[import]uid: 199068 topic_id: 26628 reply_id: 140006[/import]

I still need to know if my display objects that I insert into the scene “group” automatically get purged (removed and nilled) when the scene gets purged with storyboard or do I manually have to removeSelf and nil them? In other words: Also, I am inserting all display objects into the group. Do I manually have to remove & nil them or do they automatically get removed and nilled when the scene is purged?

Please someone answer this question!

[import]uid: 8780 topic_id: 26628 reply_id: 140963[/import]

If you do a:

group:insert(somedisplayobject)

In your createScene(), willEnterScene() or enterscene() it will be purged and nil’ed when the scene is purged.

What is not removed is sound loaded in those scenes, timers, transitions that are not finished, any Runtime listeners (listeners on those display objects will be removed).

By default, storyboard scenes are only purged on low memory event warnings. You can turn on auto-purge, or purge the scene manually. In those cases memory should be cleaned up.

The iPad 1 only has 256M of memory and you at best can expect to get in the 40-80mb range on that device depending on what else it’s doing.
[import]uid: 199310 topic_id: 26628 reply_id: 140979[/import]