Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
adding/removing children and memory usage — Gideros Forum

adding/removing children and memory usage

atilimatilim Maintainer
edited April 2012 in General questions
Hi,

I've decided to do a simple test to understand if there is a memory leak when a big hierarchy of sprites is created. I created 8000 sprites with 3 level of hierarchy, attached to the stage, removed from the stage and observed the memory usage.

Here is a sample code:
collectgarbage()
collectgarbage()
collectgarbage()
collectgarbage()
 
local mem1 = collectgarbage("count")	-- initial memory usage
 
-- create 3 levels of hierarchy where each level has 20 children (= 20*20*20 sprites)
local s0 = Sprite.new()	-- this will be the root
for i=1,20 do
	local s1 = Sprite.new()
	for j=1,20 do
		local s2 = Sprite.new()
		for k=1,20 do
			local s3 = Sprite.new()
			s2:addChild(s3)
		end				
		s1:addChild(s2)
	end	
	s0:addChild(s1)
end
 
stage:addChild(s0)	-- add the root of this hierarchy to the stage
 
collectgarbage()
collectgarbage()
collectgarbage()
collectgarbage()
 
local mem2 = collectgarbage("count")	-- memory usage after creating 8000 sprites
 
s0:removeFromParent()	-- detach from the stage and make it nil
s0 = nil
 
collectgarbage()
collectgarbage()
collectgarbage()
collectgarbage()
 
local mem3 = collectgarbage("count")	-- memory usage after detaching the hierarchy from the stage
 
print(mem1, mem2, mem3)
And this is the result:
58.28125	1539.421875	59.1982421875
mem3 is a little bigger than mem1 because of some small internal allocations and it's not a memory leak.
+1 -1 (+5 / -0 )Share on Facebook

Comments

  • what about adding event listeners to the sprites , then adding the children and removing them?
  • atilimatilim Maintainer
    edited April 2012
    After some tests with adding event listeners, again no leaks.

    Btw, in Lua, even if you delete all the fields of a table, the table continues to occupy some memory space.
    local function gc()
    	collectgarbage()
    	collectgarbage()
    	collectgarbage()
    	collectgarbage()
    end
     
    gc()
    local mem1 = collectgarbage("count")
     
    local t = {}		-- create an empty table
    for i=1,10000 do 	-- put another 10000 empty tables in it
    	t[i] = {}
    end
     
    gc()
    local mem2 = collectgarbage("count")
     
    for i=1,10000 do	-- empty the table (now this table has no fields)
    	t[i] = nil
    end
     
    gc()
    local mem3 = collectgarbage("count")
     
    t = nil				-- set table as nil
     
    gc()
    local mem4 = collectgarbage("count")
     
    print(mem1, mem2, mem3, mem4)
    The output is
    58.0234375	626.5546875	314.0546875	58.0234375
    mem3 should be much more lower but Lua keeps some memory allocated internally (even if the table is totally empty).

    Likes: AlexRu

    +1 -1 (+1 / -0 )Share on Facebook
  • I often noticed when checking code to see if there were any memory leaks (as I moved from screen to screen) that the numbers would fluctuate slightly above the expected amount and then settle down. If you do this repeatedly in a loop you can see a pattern emerge and be pretty sure you have no leaks (I also assumed it was down to some internal Lua allocation that was eventually collected later on).

    Likes: atilim

    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
    +1 -1 (+1 / -0 )Share on Facebook
  • Ironically considering Lua is supposed to be all "just forget about memory allocation and let the garbage collector sort it out", I find I actually pay more attention to making sure that not only are things removed properly but also that all potential trailing references are also cleaned up as it's easier to have a memory / resource leak in Lua than it is in C++ ???

    Good memory management should be the cornerstone of ANY app, and I'd recommend all developers to make good use of the collectgarbage() function to make sure they aren't loosing any memory unexpectedly.
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • katzekatze Member
    Hi, i dont wanted to start a new topic for this.
    so i just ask here.
    i was testing out if my app is creating memleaks, and so i added
    print (collectgarbage("count"))
    to it.
    i was wondering of constantly growing up mem usage, so i tried to find out what it is, and all that is left now from the app is this:

    function onEnterFrame()
    print (collectgarbage("count"))
    end
    stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)

    and even only with this there is still a growing memory usage.
    or is it just the consolebuffer or something? =)
  • GregBUGGregBUG Guru
    edited April 2012
    @katze

    i think is related to print function... (or as you said console buffer)

    try this...

    function onEnterFrame()
    print (collectgarbage("count"))
    collectgarbage() -- clean memory garbage
    end

    and no memory grow...

    i don't know if it's me
    but Lua garbage collector is driving me crazy....
    (yes... i'm memory paranoid)



    b-(

    ciao,
    Gianluca
    TNT ENGiNE for Gideors Studio - Particle Engine, Virtual Pad, Animator Studio, Collision Engine - DOWNLOAD NOW !!! IT'S FREE!!! -
    www.tntengine.com
  • atilimatilim Maintainer
    edited April 2012
    Hi @katze,

    It's totally related to Lua. In print function, the number returned from collectgarbage("count") is converted to string and each _unique_ string consumes some memory until they are collected.

    Change the print(collectgarbage("count")) to print(math.floor(collectgarbage("count"))) and then you can see the memory remains same.

    Likes: techdojo

    +1 -1 (+1 / -0 )Share on Facebook
  • GregBUGGregBUG Guru
    edited April 2012
    @atilim :P
    TNT ENGiNE for Gideors Studio - Particle Engine, Virtual Pad, Animator Studio, Collision Engine - DOWNLOAD NOW !!! IT'S FREE!!! -
    www.tntengine.com
  • katzekatze Member
    edited April 2012
    ah i did that math.floor() to get the result more readable, and i was wondering if floor is not working correectly or something, but now i see clearly!

    ty, so i now all is fine =)

    small extra question:
    should i just put collectgarbage() into the onEnterFrame event function?
  • @atilim - that's a nice little "hack" for reporting memory usage, I'll have to remember that! :)
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • AlexRuAlexRu Member
    edited May 2012
    @atilim, thanx very much. I was looking for memory leaks in my code when move from screen to screen ~X( . It was tables. I just added table = nil in REMOVED_FROM_STAGE Event and there are no leaks more. :D

    I think It will good if "Memory usage" subchapter will in Ultimate Guide.

    May anybody explain me why call collectgarbage() for 4 times in gc()??
    local function gc()
    	collectgarbage()
    	collectgarbage()
    	collectgarbage()
    	collectgarbage()
    end

Sign In or Register to comment.