NOTE: This tutorial is outdated and has been replaced by the Performance and Optimization guide. Please refer to this guide for current details and usage examples.
  1. So if I have a display group and I use display.remove() to remove the whole group at one time, can I simply nil out the group declaration afterward, or need I nil out all individual display objects as well?

    • Jonathan Beebe says:

      @Shane: If you have objects in a group, all you need to do is remove the group and the rest should be taken care of for you.

      @ Satheesh: Glad you found value in it!

  2. Another HIT! Thanks Jon.

    By the way am I right to think that I use director (1.2) that display objects are automatically cleaned up when when switching out of a screen (ie going back to a main menu screen from a game screen for instance). I am using the director clean() to delete runtime listeners, transistions, sounds.

    Is that the correct way of doing things with director?

    Thanks again, I am always excited to see another of this great series Of tutorials. Thank you for taking the time to doing this.

    Mo

  3. Jon, you rock. Thank you! Every time you come out with one of these I throw it in my bookmark folder for later review. The quality of these articles is fantastic!! Great subject matter, too!

    Thanks again!!

    -Mario

  4. This variation only prints changes in the memory status:

    local prevTextMem = 0
    local prevMemCount = 0
    local monitorMem = function()
    collectgarbage()
    local memCount = collectgarbage(“count”)
    if (prevMemCount ~= memCount) then
    print( “MemUsage: ” .. memCount)
    prevMemCount = memCount
    end
    local textMem = system.getInfo( “textureMemoryUsed” ) / 1000000
    if (prevTextMem ~= textMem) then
    prevTextMem = textMem
    print( “TexMem: ” .. textMem )
    end
    end

    Runtime:addEventListener( “enterFrame”, monitorMem )

  5. This is very nice. My game has a lot of one-time transitions in it, i did not realize i needed to cancel them even after they were completed. I had this code in my main.lua and could not for the life of me figure out why I had such a bad memory leak!

    thanks a lot

    amanda

  6. @amanda,

    You don’t need to cancel transitions that have completed. They only need to be cancelled if they are still running when you need to switch screens (e.g., using Director).

  7. Just saw this…. HANDY!

    Another tip: if you need globals for e.g. global state, put their declaration in a separate module that you require as first line in main.lua

    That way, keeping track of globals that might leak is so much easier.
    And, you force yourself to think twice before using globals.

  8. I’m trying to track down a memory leak. I have noticed the amount of memory used jumps a little bit when the mouse is clicked – there are no event listeners running, so what is causing this? Sometimes it jumps a little and sometimes it does not.

  9. I am trying to use the suggestion for cleaning timers and transitions. There is something I don’t understand. Does “timerStash.newTimer = timer.performWithDelay( …” really add a new item to the table? I’m maybe missing something but it doesn’t seem to work for me. When I do “table.insert” instead, it works as intended. What am I missing?

    Thanks in advance

  10. @Eugen Stolin, @Fixdit

    The line timerStash.newTimer = timer.performWithDelay(.. does add a new item to the table, but it always does so under the key “newTimer”. It’s the equivalent of saying timerStash[“newTimer”] = timer.performWithDelay(.. This means if you’re adding multiple timers with the line timerStash.newTimer = timer.performWithDelay(.., you’re constantly overwriting the previous timer under the key “newTimer”.

    “table.insert” is working for you because the table handles key creation for you, and you simply have to pass in the value. I think by default the keys will be an incremented integer (0, 1, 2 .. n), so you won’t have the overwriting problem mentioned above.

    I assume that using table.insert is fine if you don’t care about what key is generated. If you do care, then you’ll have to provide the key yourself, and keep them unique. So if you had multiple timers to add you would simply declare them like so:

    timerStash.characterTimer = timer.performWithDelay(..
    timerStash.sceneTimer = timer.performWithDelay(..

    and so on…

    The point is that different timers added to the table need to have different keys.

    “cancelAllTimers” will still work with these unique keys because it simply goes through all of the table’s key/value pairs, and cancels/nils everything.

  11. If I have a lot of items in a group and each display object in the group is added to the physics engine as a body and then I remove the parent group that holds all the physics body display objects …. is there anything special there that I need to do ?

  12. To add timers or transitions to the stash incrementally as you go (as long as you don’t care about their names, like for one-offs or something) you can do:

    timerStash[#timerStash+1] = timer.performWithDelay(consoleSpeed, ScrollDialogBox, 0)

    and then call the CancelAllTimers function and it will work just peachy

  13. Ok, so is this right?

    I am using the director class…here is how I am managing memory…

    Every display object I create, I nil it out. I do this by incorporating a cleanup function for any transitions that take place…

    Every event listener I create, I also nil out, with the exception of Runtime, because that produced the same result, in my simulation, as dividing by zero.

    Every timer I create, I nil out. So I have a function that looks like this…

    –inside after win function or restart(pseudo)
    …if win == true then
    …other code here
    clean()
    …end

    –clean functions
    local function cleanDisplay()

    if object ~= nil then
    display.remove( object )
    object – nil
    end

    end

    local function cleanListeners()

    object._functionListeners = nil
    object._tableListeners = nil

    end

    local function cleanTimers()

    if timerStash.myTimer ~= nil then
    timer.cancel( timerStash.myTimer )
    end
    end

    function clean()

    cleanDisplay()
    cleanListeners()
    cleanTimers()

    end

    I am using this model right now, and it seems to work when I am monitoring memory. But it is a lot of code, and I have a minimum of display objects and listeners and timers. Can I get some feedback as to whether or not this is okay?

  14. In database i update some data, it insert my data values in the table but if i relaunch it reset the table values i think it not storing in db if any knew the solution plz help me…………

  15. Most often you would have transitions that run and end in a scene. It’s only the currently running transitions that need to be canceled. If you’re adding every transition to a table you could easily end up with transition that have already competed in your table when the scene exits.

  16. Hi there! I have a question about this…

    Okay, we don’t need to cancel transitions that have completed… but we need “nil-out” them even if it had been completed ? or doesn’t matter?

    I mean… when a transition ends, value is nil automatically?

    Thanks!!

  17. Very good! My game was getting up to 1.6 mb of memory used before I start using the function with collectgarbage() inside it. Now, the maximum it reaches is 600kb! :D

  18. I’m using the storyboard API when I leave and then return to my in game scene I notice that the memory usage has crept up. I’ve stripped the code right back to the bare minimum and the memory usage only creeps up a tiny amount but I have the understanding that It shouldn’t go up at all, i.e. if there were no memory leak.

    I remove the in game scene “storyboard.removeScene( previous_scene )” on the restart scene (which just returns to the in game scene again).

    I’ve tried removing all objects, setting them to nil and manually removing event listeners.

    I think I must be missing something but have no idea what. i ‘d like really like to get this sussed before developing the game further. I’m I correct in thinking that the memory usage should be the same every time the in game scene loads?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>