Memory Leak Problem

local memory_text = display.newText( “Hello”, 5, 5, native.systemFont, 16 )

memory_text:setTextColor( 255, 0, 0 )

memory_text.x = display.contentCenterX

 

local monitorMem = function()

    collectgarbage()

    local textMem = math.round( system.getInfo( “textureMemoryUsed” ) / 1000000 )

    memory_text.text = “Mem:”…math.round( collectgarbage(“count”) ) … " tex:"… textMem

end

 

Runtime:addEventListener( “enterFrame”, monitorMem )

 

this is the code that I use to monitorate my memory… but in my game I always get a leak in my memory that make the game very slowly in certain time…

 

I have noted that my problem is when I fired a bullet in my game… I have a upgrade in my memory status and when I remove my bullet I don’t have the same size of memory back… and I don’t understand why… because in my remove function I have all the stuffs to remove this bullet…

check:

 

local function remove_bullet( bullet )

    local index = table.indexOf( bullet_array, bullet )

    transition.cancel( bullet.transition )

    table.remove( bullet_array, index )

    display.remove( bullet )

    bullet = nil

end

 

someone can help me with this problem? I can’t release a game that will freeze some time in the game =T

 

thanks

I think you have to remove the display object first, then remove the bullet from the table. Also, do you have any timers associated with the bullet, or just a transition? That should be referenced and canceled as well.

module( ..., package.seeall ) -- -- -- Waves of Enemies function new() local movieclip = require("movieclip") local physics = require("physics") local Torres = require( "torresFase1" ) -- -- local game\_group = display.newGroup() local tile\_group = display.newGroup() local alien\_group = display.newGroup() game\_group:insert( tile\_group ) game\_group:insert( alien\_group ) -- -- Variaveis -- local TILE\_ROWS = 5 local TILE\_COLS = 9 local TILE\_SIZE = 103 local TILE\_MARGIN = 2 local ALIEN\_SPEED = 1000 / 10 local alien\_wave\_index = 1 -- Use this to keep track of the current wave local alien\_wave\_array -- -- Funçoes -- local criaFundoCenario local make\_grid local make\_wave local next\_wave local make\_alien local remove\_alien -- -- Arrays -- local defense\_array = {} local alien\_array = {} local bullet\_array = {} local arrayTorres = Torres.torres local defense\_type\_array = {} local ultimaDefesa\_array = {} local gameover\_array = {} local alien\_type\_array = { { name="normal", velocidade = 50, vida=1, dano=1 }, { name="fast", velocidade = 50, vida=1, dano=0.5 }, { name="slow", velocidade = 50, vida=1, dano=1.5 } } -- -- -------------------------------------------------------------------------------------- --- Grid e Fundo --- -------------------------------------------------------------------------------------- criaFundoCenario = function() local fundo = display.newImageRect( "cenario.jpg", 1024, 768 ) fundo.x = \_W/2 fundo.y = \_H/2 tile\_group:insert( fundo ) return fundo end criaFundoCenario() make\_grid = function() for row = 1, TILE\_ROWS, 1 do for col = 1, TILE\_COLS, 1 do local tile = display.newRect( 0, 0, TILE\_SIZE+1, TILE\_SIZE+1 ) tile.x = ( TILE\_SIZE + TILE\_MARGIN ) \* col - 15 tile.y = ( TILE\_SIZE + TILE\_MARGIN ) \* row + 98 tile.has\_defense = false tile.col = col tile.row = row tile.alpha = 0.01 --tile:addEventListener( "touch", touch\_tile ) tile\_group:insert( tile ) end end return tile end make\_grid() -------------------------------------------------------------------------------------- -- -- -------------------------------------------------------------------------------------- --- Cria Waves --- -------------------------------------------------------------------------------------- -- Add an array to hold a wave of enemies alien\_wave\_array = { { time=1000, -- Time between enemies count=0, -- Number of enemies in wave pool={1,2,3}, -- Number and type of enemies in wave delay=2000 -- Time to start next wave } , { time=1500, -- Time between enemies count=1, -- Number of enemies in wave pool={1,2,3}, -- Number and type of enemies in wave delay=5000 } } -- Add this function to mange creating enemies that attack in waves. make\_wave = function() local wave\_table = alien\_wave\_array[alien\_wave\_index] local wave\_time = wave\_table.time local wave\_count = wave\_table.count local delay\_after\_wave = wave\_table.delay alien\_timer = timer.performWithDelay( wave\_time, make\_alien, wave\_count ) local time\_til\_next\_wave = ( wave\_time \* wave\_count ) + delay\_after\_wave wave\_timer = timer.performWithDelay( time\_til\_next\_wave, next\_wave, 1 ) end -- Called at the end of each wave next\_wave = function() alien\_wave\_index = alien\_wave\_index + 1 if alien\_wave\_index \> #alien\_wave\_array then --timer.cancel( energy\_timer ) print( "ALL WAVES COMPLETE" ) else print( "next wave" ) make\_wave() end end make\_wave() -------------------------------------------------------------------------------------- -- -- -------------------------------------------------------------------------------------- --- Cria Inimigos --- -------------------------------------------------------------------------------------- remove\_alien = function( alien ) local explosionAlien = display.newImageRect( "tiros/explosaoAlien.png", 50, 48 ) explosionAlien.x = alien.x explosionAlien.y = alien.y local removeExplostionFunc = function() transExplosion = nil display.remove( explosionAlien ) explosionAlien = nil end local transExplosion = transition.to( explosionAlien, { time = 600, alpha = 0, width = 80, height = 80, onComplete = removeExplostionFunc } ) local index = table.indexOf( alien\_array, alien ) transition.cancel( alien.transition ) alien.transition = nil alien:stop() table.remove( alien\_array, index ) display.remove( alien ) alien = nil print( 'Deletou' ) end make\_alien = function() local alien\_wave\_pool = alien\_wave\_array[alien\_wave\_index].pool -- get the current pool of alien types local alien\_type\_index = alien\_wave\_pool[math.random( 1, #alien\_wave\_pool )] -- Get a random type index local alien\_type = alien\_type\_array[alien\_type\_index] -- Get a random alien type local alienTipo = alien\_type\_array[alien\_type\_index].name local alien = movieclip.newAnim{ "inimigos/1/1.png", "inimigos/1/2.png", "inimigos/1/3.png", "inimigos/1/4.png", "inimigos/1/5.png", "inimigos/1/6.png" } --"inimigos/1/7.png", "inimigos/1/8.png", "inimigos/1/9.png", "inimigos/1/10.png", "inimigos/1/11.png", "inimigos/1/12.png", "inimigos/1/13.png", "inimigos/1/14.png", "inimigos/1/15.png", "inimigos/1/16.png", "inimigos/1/17.png", "inimigos/1/18.png", "inimigos/1/19.png", "inimigos/1/20.png", "inimigos/1/21.png" } alien.alien\_type = alien\_type alien.tipo = alienTipo alien.transitionCancelada = false local col = 9 local row = math.random( 1, TILE\_ROWS ) alien.row = row alien.col = col alien.x = 1024 alien.y = row \* ( TILE\_SIZE + TILE\_MARGIN ) + 98 alien.vida = alien\_type.vida alien.dano = alien\_type.dano if alien\_type.name == "normal" then alien:setSpeed(0.15) alien:play() elseif alien\_type.name == "fast" then alien:setSpeed(0.2) alien:play() elseif alien\_type.name == "slow" then alien:setSpeed(0.12) alien:play() end local t = 100 \* alien\_type.velocidade alien.transition = transition.to( alien, {x = -50, time=t, onComplete=remove\_alien} ) alien\_group:insert( alien ) table.insert( alien\_array, alien ) return alien end -------------------------------------------------------------------------------------- -- -- -------------------------------------------------------------------------------------- --- Teste de Memoria --- -------------------------------------------------------------------------------------- local memory\_text = display.newText( "Hello", 5, 130, native.systemFont, 16 ) memory\_text:setTextColor( 255, 0, 0 ) memory\_text.x = display.contentCenterX local monitorMem = function() collectgarbage() local textMem = math.round( system.getInfo( "textureMemoryUsed" ) / 1000000 ) memory\_text.text = "Mem:"..math.round( collectgarbage("count") ) .. " tex:".. textMem end Runtime:addEventListener( "enterFrame", monitorMem ) -------------------------------------------------------------------------------------- -- -- return game\_group end

 

 

this is an sample of my TD game… in this sample I put only 1 enemy in the screen… my initial memory is 259 and when I put the enemy in game it up to 268 but when I remove my enemy the memory don’t back to 259 as it should be… is something that I don’t understand why… because I’m setting nil to all variables and stoping transitions and timers…

 

someone can help me works it out??

 

thanks

You need to remove the alien before you delete it from the table.  You also need to set the table entry to nil before you remove it as it also holds a reference to the display memory.

 

 

display.remove( alien ) alien = nil table.remove( alien\_array, index ) alien\_array = nil

 

 

like that?

 

still on 261

[lua]

display.remove( alien )
alien = nil
alien_array[index] = nil

table.remove( alien_array, index )
[/lua]

 

alien_array = nil would blow away your whole table.

 

yes I image that… but still not working… still in 261 and the normal is 259

 

one thing that I noticed is in “explosionalien” is that if I use this image to make a explosion, after I remove it still have 1 in memory that stuck in

I’m doing something wrong with empty this image too?

I think you might have a scoping problem where you are trying to use a variable before you define it:

[lua]

        local transExplosion

        local removeExplostionFunc = function()
            transExplosion = nil  – because this reference to transExplosion was before the local version below it, it’s referencing a global named transExplosion, not the one you create below.  Try moving the definition above this function.
            display.remove( explosionAlien )
            explosionAlien = nil
        end
        
        transExplosion = transition.to( explosionAlien, { time = 600, alpha = 0, width = 80, height = 80, onComplete = removeExplostionFunc } )
                   

[/lua]

local explosionAlien = display.newImageRect( "tiros/explosaoAlien.png", 50, 48 ) explosionAlien.x = alien.x explosionAlien.y = alien.y local transExplosion local removeExplostionFunc = function() transExplosion = nil display.remove( explosionAlien ) explosionAlien = nil end transExplosion = transition.to( explosionAlien, { time = 600, alpha = 0, width = 80, height = 80, onComplete = removeExplostionFunc } ) 

 

 

still not working… really don’t know where I’m stucking memory

 

is strange this stuck memory… because I’m setting nil to everything and stopping all ):

 

Thanks for your helping Rob but I don’t know if we will be able to fix this =/  I really hope so

I think you have to remove the display object first, then remove the bullet from the table. Also, do you have any timers associated with the bullet, or just a transition? That should be referenced and canceled as well.

module( ..., package.seeall ) -- -- -- Waves of Enemies function new() local movieclip = require("movieclip") local physics = require("physics") local Torres = require( "torresFase1" ) -- -- local game\_group = display.newGroup() local tile\_group = display.newGroup() local alien\_group = display.newGroup() game\_group:insert( tile\_group ) game\_group:insert( alien\_group ) -- -- Variaveis -- local TILE\_ROWS = 5 local TILE\_COLS = 9 local TILE\_SIZE = 103 local TILE\_MARGIN = 2 local ALIEN\_SPEED = 1000 / 10 local alien\_wave\_index = 1 -- Use this to keep track of the current wave local alien\_wave\_array -- -- Funçoes -- local criaFundoCenario local make\_grid local make\_wave local next\_wave local make\_alien local remove\_alien -- -- Arrays -- local defense\_array = {} local alien\_array = {} local bullet\_array = {} local arrayTorres = Torres.torres local defense\_type\_array = {} local ultimaDefesa\_array = {} local gameover\_array = {} local alien\_type\_array = { { name="normal", velocidade = 50, vida=1, dano=1 }, { name="fast", velocidade = 50, vida=1, dano=0.5 }, { name="slow", velocidade = 50, vida=1, dano=1.5 } } -- -- -------------------------------------------------------------------------------------- --- Grid e Fundo --- -------------------------------------------------------------------------------------- criaFundoCenario = function() local fundo = display.newImageRect( "cenario.jpg", 1024, 768 ) fundo.x = \_W/2 fundo.y = \_H/2 tile\_group:insert( fundo ) return fundo end criaFundoCenario() make\_grid = function() for row = 1, TILE\_ROWS, 1 do for col = 1, TILE\_COLS, 1 do local tile = display.newRect( 0, 0, TILE\_SIZE+1, TILE\_SIZE+1 ) tile.x = ( TILE\_SIZE + TILE\_MARGIN ) \* col - 15 tile.y = ( TILE\_SIZE + TILE\_MARGIN ) \* row + 98 tile.has\_defense = false tile.col = col tile.row = row tile.alpha = 0.01 --tile:addEventListener( "touch", touch\_tile ) tile\_group:insert( tile ) end end return tile end make\_grid() -------------------------------------------------------------------------------------- -- -- -------------------------------------------------------------------------------------- --- Cria Waves --- -------------------------------------------------------------------------------------- -- Add an array to hold a wave of enemies alien\_wave\_array = { { time=1000, -- Time between enemies count=0, -- Number of enemies in wave pool={1,2,3}, -- Number and type of enemies in wave delay=2000 -- Time to start next wave } , { time=1500, -- Time between enemies count=1, -- Number of enemies in wave pool={1,2,3}, -- Number and type of enemies in wave delay=5000 } } -- Add this function to mange creating enemies that attack in waves. make\_wave = function() local wave\_table = alien\_wave\_array[alien\_wave\_index] local wave\_time = wave\_table.time local wave\_count = wave\_table.count local delay\_after\_wave = wave\_table.delay alien\_timer = timer.performWithDelay( wave\_time, make\_alien, wave\_count ) local time\_til\_next\_wave = ( wave\_time \* wave\_count ) + delay\_after\_wave wave\_timer = timer.performWithDelay( time\_til\_next\_wave, next\_wave, 1 ) end -- Called at the end of each wave next\_wave = function() alien\_wave\_index = alien\_wave\_index + 1 if alien\_wave\_index \> #alien\_wave\_array then --timer.cancel( energy\_timer ) print( "ALL WAVES COMPLETE" ) else print( "next wave" ) make\_wave() end end make\_wave() -------------------------------------------------------------------------------------- -- -- -------------------------------------------------------------------------------------- --- Cria Inimigos --- -------------------------------------------------------------------------------------- remove\_alien = function( alien ) local explosionAlien = display.newImageRect( "tiros/explosaoAlien.png", 50, 48 ) explosionAlien.x = alien.x explosionAlien.y = alien.y local removeExplostionFunc = function() transExplosion = nil display.remove( explosionAlien ) explosionAlien = nil end local transExplosion = transition.to( explosionAlien, { time = 600, alpha = 0, width = 80, height = 80, onComplete = removeExplostionFunc } ) local index = table.indexOf( alien\_array, alien ) transition.cancel( alien.transition ) alien.transition = nil alien:stop() table.remove( alien\_array, index ) display.remove( alien ) alien = nil print( 'Deletou' ) end make\_alien = function() local alien\_wave\_pool = alien\_wave\_array[alien\_wave\_index].pool -- get the current pool of alien types local alien\_type\_index = alien\_wave\_pool[math.random( 1, #alien\_wave\_pool )] -- Get a random type index local alien\_type = alien\_type\_array[alien\_type\_index] -- Get a random alien type local alienTipo = alien\_type\_array[alien\_type\_index].name local alien = movieclip.newAnim{ "inimigos/1/1.png", "inimigos/1/2.png", "inimigos/1/3.png", "inimigos/1/4.png", "inimigos/1/5.png", "inimigos/1/6.png" } --"inimigos/1/7.png", "inimigos/1/8.png", "inimigos/1/9.png", "inimigos/1/10.png", "inimigos/1/11.png", "inimigos/1/12.png", "inimigos/1/13.png", "inimigos/1/14.png", "inimigos/1/15.png", "inimigos/1/16.png", "inimigos/1/17.png", "inimigos/1/18.png", "inimigos/1/19.png", "inimigos/1/20.png", "inimigos/1/21.png" } alien.alien\_type = alien\_type alien.tipo = alienTipo alien.transitionCancelada = false local col = 9 local row = math.random( 1, TILE\_ROWS ) alien.row = row alien.col = col alien.x = 1024 alien.y = row \* ( TILE\_SIZE + TILE\_MARGIN ) + 98 alien.vida = alien\_type.vida alien.dano = alien\_type.dano if alien\_type.name == "normal" then alien:setSpeed(0.15) alien:play() elseif alien\_type.name == "fast" then alien:setSpeed(0.2) alien:play() elseif alien\_type.name == "slow" then alien:setSpeed(0.12) alien:play() end local t = 100 \* alien\_type.velocidade alien.transition = transition.to( alien, {x = -50, time=t, onComplete=remove\_alien} ) alien\_group:insert( alien ) table.insert( alien\_array, alien ) return alien end -------------------------------------------------------------------------------------- -- -- -------------------------------------------------------------------------------------- --- Teste de Memoria --- -------------------------------------------------------------------------------------- local memory\_text = display.newText( "Hello", 5, 130, native.systemFont, 16 ) memory\_text:setTextColor( 255, 0, 0 ) memory\_text.x = display.contentCenterX local monitorMem = function() collectgarbage() local textMem = math.round( system.getInfo( "textureMemoryUsed" ) / 1000000 ) memory\_text.text = "Mem:"..math.round( collectgarbage("count") ) .. " tex:".. textMem end Runtime:addEventListener( "enterFrame", monitorMem ) -------------------------------------------------------------------------------------- -- -- return game\_group end

 

 

this is an sample of my TD game… in this sample I put only 1 enemy in the screen… my initial memory is 259 and when I put the enemy in game it up to 268 but when I remove my enemy the memory don’t back to 259 as it should be… is something that I don’t understand why… because I’m setting nil to all variables and stoping transitions and timers…

 

someone can help me works it out??

 

thanks

You need to remove the alien before you delete it from the table.  You also need to set the table entry to nil before you remove it as it also holds a reference to the display memory.

 

 

display.remove( alien ) alien = nil table.remove( alien\_array, index ) alien\_array = nil

 

 

like that?

 

still on 261

[lua]

display.remove( alien )
alien = nil
alien_array[index] = nil

table.remove( alien_array, index )
[/lua]

 

alien_array = nil would blow away your whole table.

 

yes I image that… but still not working… still in 261 and the normal is 259

 

one thing that I noticed is in “explosionalien” is that if I use this image to make a explosion, after I remove it still have 1 in memory that stuck in

I’m doing something wrong with empty this image too?

I think you might have a scoping problem where you are trying to use a variable before you define it:

[lua]

        local transExplosion

        local removeExplostionFunc = function()
            transExplosion = nil  – because this reference to transExplosion was before the local version below it, it’s referencing a global named transExplosion, not the one you create below.  Try moving the definition above this function.
            display.remove( explosionAlien )
            explosionAlien = nil
        end
        
        transExplosion = transition.to( explosionAlien, { time = 600, alpha = 0, width = 80, height = 80, onComplete = removeExplostionFunc } )
                   

[/lua]

local explosionAlien = display.newImageRect( "tiros/explosaoAlien.png", 50, 48 ) explosionAlien.x = alien.x explosionAlien.y = alien.y local transExplosion local removeExplostionFunc = function() transExplosion = nil display.remove( explosionAlien ) explosionAlien = nil end transExplosion = transition.to( explosionAlien, { time = 600, alpha = 0, width = 80, height = 80, onComplete = removeExplostionFunc } ) 

 

 

still not working… really don’t know where I’m stucking memory

 

is strange this stuck memory… because I’m setting nil to everything and stopping all ):

 

Thanks for your helping Rob but I don’t know if we will be able to fix this =/  I really hope so