Difference in system memory usage on device and simulator?

https://portal.coronalabs.com/bug-submission

Thanks for the link. I have uploaded the file with a description.

Can you verify that the sample you uploaded has the problem? I can’t ask an engineer to look into this if it doesn’t have the problem.   Please help us help you.

Rob

Please note I just send another file version because I forgot to comment out the “solution” for the problem in the scene2 file.

I can not test it on device right now. I will update here if I have tested the sample on device! Thanks for your help!

Maybe someone wants to test it on device?.. if so, I just have changed some things in the composer sample from the sample Corona files.

Here are the changed files:

The scene2.lua file:

--------------------------------------------------------------------------------- -- -- scene2.lua -- --------------------------------------------------------------------------------- local composer = require( "composer" ) local scene = composer.newScene() local image, text1, text2, text3, memTimer -- added module -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local module=require ("load\_module\_stuff") local initmodulestuff=module.initmodulestuff local gfx=module.gfx local groups=module.groups -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local function onSceneTouch( self, event )     if event.phase == "began" then                  composer.gotoScene( "scene3", "fade", 400  )                  return true     end end function scene:create( event )     local sceneGroup = self.view          image = display.newImage( "bg2.jpg" )     image.x = display.contentCenterX     image.y = display.contentCenterY          sceneGroup:insert( image )          image.touch = onSceneTouch          text1 = display.newText( "Scene 2", 0, 0, native.systemFontBold, 24 )     text1:setFillColor( 255 )     text1.x, text1.y = display.contentWidth \* 0.5, 50     sceneGroup:insert( text1 )          text2 = display.newText( "MemUsage: ", 0, 0, native.systemFont, 16 )     text2:setFillColor( 255 )     text2.x, text2.y = display.contentWidth \* 0.5, display.contentHeight \* 0.5     sceneGroup:insert( text2 )          text3 = display.newText( "Touch to continue.", 0, 0, native.systemFontBold, 18 )     text3:setFillColor( 255 ); text3.isVisible = false     text3.x, text3.y = display.contentWidth \* 0.5, display.contentHeight - 100     sceneGroup:insert( text3 )          print( "\n2: create event" ) end function scene:show( event )          local phase = event.phase          if "did" == phase then              print( "2: show event, phase did" )              -- remove previous scene's view         composer.removeScene( "scene1" )              -- Update Lua memory text display         local showMem = function()             image:addEventListener( "touch", image )             text3.isVisible = true             text2.text = text2.text .. string.format("%.2g", collectgarbage("count")/1000) .. "MB"             text2.x = display.contentWidth \* 0.5         end         memTimer = timer.performWithDelay( 1000, showMem, 1 )         -- we now init the module         -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*         local sceneGroup = self.view         initmodulestuff (sceneGroup)         -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*          end      end function scene:hide( event )          local phase = event.phase     if "will" == phase then              print( "2: hide event, phase will" )              -- remove touch listener for image         image:removeEventListener( "touch", image )              -- cancel timer         timer.cancel( memTimer ); memTimer = nil;              -- reset label text         text2.text = "MemUsage: "     end end function scene:destroy( event )          print( "((destroying scene 2's view))" )     -- the following code is making a difference ONLY on device when active and not the simulator:     -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*     --[[    if gfx.circleobj then         if gfx.circleobj.mytext1 then             display.remove(gfx.circleobj.mytext1)             gfx.circleobj.mytext1=nil         end         if gfx.circleobj.mytext2 then             display.remove(gfx.circleobj.mytext2)             gfx.circleobj.mytext2=nil         end         if gfx.circleobj.mytext3 then             display.remove(gfx.circleobj.mytext3)             gfx.circleobj.mytext3=nil         end         if gfx.circleobj.mytext4 then             display.remove(gfx.circleobj.mytext4)             gfx.circleobj.mytext4=nil         end     end     --]]     -- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*     -- we now remove the graphics from the module     for k,v in pairs( gfx ) do         if v then             display.remove ( v )             v=nil             if gfx[k] then                 display.remove (gfx[k])                 gfx[k]=nil             end         end         if #gfx then             for x=#gfx,1,-1 do                 if gfx[x] then                     display.remove(gfx[x])                     gfx[x]=nil                 end             end         end     end     if groups then         if #groups then             for x=#groups,1,-1 do                 if groups[x] then                     display.remove(groups[x])                     groups[x]=nil                 end             end         end         for k,v in pairs( groups ) do             if v then                display.remove ( v )                v=nil                if groups[k] then                     display.remove (groups[k])                     groups[k]=nil                 end             end         end     end end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene

And the module file I have added:

load_module_stuff.lua

-- the module for scene 2 local mod={} local gfx={circleobj} local groups={gui} local createtextfunction = function()     local textoptions=         {             text = "My Circle Text",                  fontSize = 12,             align = "left"  -- Alignment parameter         }     -- adding some text direct to the circle     gfx.circleobj.mytext1=display.newText(textoptions)     gfx.circleobj.mytext2=display.newText(textoptions)     gfx.circleobj.mytext3=display.newText(textoptions)     gfx.circleobj.mytext4=display.newText(textoptions)     gfx.circleobj.mytext1.x=64     gfx.circleobj.mytext1.y=96     gfx.circleobj.mytext2.x=64     gfx.circleobj.mytext2.y=106     gfx.circleobj.mytext3.x=64     gfx.circleobj.mytext3.y=116     gfx.circleobj.mytext4.x=64     gfx.circleobj.mytext4.y=126     groups.gui:insert(gfx.circleobj.mytext1)     groups.gui:insert(gfx.circleobj.mytext2)     groups.gui:insert(gfx.circleobj.mytext3)     groups.gui:insert(gfx.circleobj.mytext4) end local initmodulestuff=function(sceneGroup)     groups.gui=display.newGroup( )     gfx.circleobj=display.newCircle(0,0,28)     -- position stuff     gfx.circleobj.x=64     gfx.circleobj.y=64     groups.gui:insert(gfx.circleobj)     createtextfunction()     sceneGroup:insert (groups.gui) end mod.gfx=gfx mod.groups=groups mod.initmodulestuff=initmodulestuff return mod

I will test it on device asap but it will take some days I guess.

I’ve never been happy with the Composer sample app because if you run it, it appears to be leaking memory. I took a few minutes and made a few changes to it today. Here is one of the snippets that I changed:

function scene:show( event ) local phase = event.phase if "did" == phase then print( "1: show event, phase did" ) -- remove previous scene's view composer.removeScene( "scene4" ) collectgarbage("collect") -- #1 -- Update Lua memory text display local showMem = function() image:addEventListener( "touch", image ) text3.isVisible = true text2.text = text2.text .. string.format("%.3g MB, %.3g MB", collectgarbage("count")/1024, system.getInfo("textureMemoryUsed")/(1024 \* 1024)) -- #2 text2.x = display.contentWidth \* 0.5 end memTimer = timer.performWithDelay( 1000, showMem, 1 ) end end function scene:hide( event ) local phase = event.phase if "will" == phase then print( "1: hide event, phase will" ) -- remove touch listener for image image:removeEventListener( "touch", image ) -- cancel timer timer.cancel( memTimer ); memTimer = nil; -- reset label text text2.text = "MemUsage: " elseif "did" == phase then composer.removeScene("scene1") -- #3 end end

There are three changes:

#1 – I force collect garbage after removing the previous scene. Lua garbage collection doesn’t happen on a fixed timer. Lua frees up memory when it feels it needs to. Assuming that memory is freed after 1 second after removing a scene is just a bad assumption on our part. To baseline things, now when the scene is removed, garbage is collected right away.

While I would highly recommend letting Lua collect garbage on its own schedule if you’re hunting a memory leak you have to control the collection yourself. 

#2 – The scene only prints Lua memory, not texture memory. display.newCircle/newText are consuming texture memory as well as Lua memory. I added printing out texture memory as well. I increased the number of decimal places to three and I corrected the Megabyte calculation. Computers use 1024 and not 1000. Metric is a power of 10 measure, Memory/Storage etc. is a power of 2 measure. Some other general clean up was added to the command to better demonstrate the power of string.format.

#3 – You can successfully remove the current scene but only in the scene:hide() function during the “did” phase. It’s a bit redundant with the removal of the previous scene in scene:show(), but I just wanted to make sure the scene’s getting removed and show this technique.

When running it on the simulator, memory is perfect. Each scene reports an effective same amount of memory. On my iPhone 10 (iOS 12.1), the memory per scene is actually a little less than the simulator, but I can run through the scenes multiple times and not see a drop of memory increase.

When testing this case, when using this sample, I would recommend adding at least changes #1 and #2 above. Adding #3 won’t hurt. 

I don’t see a memory leak.

Rob

Thanks for all your help!

I finally found the part in my code which is leaking about 100KB when a scene is reloaded or another loaded and the first one loaded again.

Here is the “problematic” function:

RetryMission = function(Button)     -- checking for bought game:     local file = io.open( \_G.path, "r" )     -- we first ask if the level should be left and progress lost AND if so, we have to save the current info.. or?     local onComplete=function(event)         -- Handler that gets notified when the alert closes           if ( event.action == "clicked" ) then                 local i = event.index                 if ( i == 1 ) then                     -- Do nothing; dialog will simply dismiss                     -- but we have to move back the button appearance now:                     if Button then                         --Button:setFrame(1)                         Button.y=Button.y-2                     end                 else                                          composer.state.nextscene="textscreen" -- the same "level" is now startd again                     -- save current stats:                     if \_G.generatedZufallsMap==1 or \_G.generatedEndlessTestMap==1 then                         -- do nothing in random map                     else                         loadsave.saveTable(MyLevelUnlockInfo,\_G.levelInfoFileName)                     end                     --composer.state.nextscene="textscreen"                     func.deleteGraphics()                     \_G.LoadnextsceneFunc ("in")                                     end             end      end      -- we check the language and then show the correct texts:           local language = system.getPreference( "locale", "language")     -- new in version 2.3 we aded the timer as local     if \_G.globallanguage=="de" then         local do1=performWithDelay(1,function() native.showAlert("Mission abbrechen?", "Möchtest Du die Mission wirklich verlassen?",{ "Nein", "JA!" },onComplete) end,1)     elseif \_G.globallanguage=="fr" then         local do1=performWithDelay(1,function() native.showAlert("Voulez-vous vraiment quitter la Mission?", "Cliquez sur OUI et quitter la mission.",{ "Non", "OUI!" },onComplete) end,1)     elseif \_G.globallanguage=="it" then         local do1=performWithDelay(1,function() native.showAlert("Vuoi davvero lasciare la missione?", "Fare clic su Sì e lasciare la missione.",{ "No", "Sì!" },onComplete) end,1)     elseif \_G.globallanguage=="es" then         local do1=performWithDelay(1,function() native.showAlert("De verdad quieres salir de la Misión?", "Haga clic en SÍ y dejar la misión.",{ "No", "SÍ!" },onComplete) end,1)     elseif \_G.globallanguage=="no" then         local do1=performWithDelay(1,function() native.showAlert("Avbryt oppdrag?", "Vil du virkelig forlate oppdraget?",{ "Nei!", "Ja!" },onComplete) end,1)     elseif \_G.globallanguage=="nl" then         local do1=performWithDelay(1,function() native.showAlert("Missie annuleren?", "Wil je echt de missie verlaten?",{ "Nee!", "Yes!" },onComplete) end,1)     elseif \_G.globallanguage=="dk" then         local do1=performWithDelay(1,function() native.showAlert("Annuller mission?", "Vil du virkelig forlade missionen?",{ "Nej!", "Ja!" },onComplete) end,1)     elseif \_G.globallanguage=="se" then         local do1=performWithDelay(1,function() native.showAlert("Avbryt uppdrag?", "Vill du verkligen lämna uppdraget?",{ "Nej!", "Yes!" },onComplete) end,1)     elseif \_G.globallanguage=="fi" then         local do1=performWithDelay(1,function() native.showAlert("Peruuta tehtävä?", "Haluatko todella lähteä lähetystyöstä?",{ "Ei!", "Kyllä!" },onComplete) end,1)     elseif \_G.globallanguage=="ru" then         local do1=performWithDelay(1,function() native.showAlert("Вы действительно хотите покинуть миссию?", "Нажмите Да! и оставить миссию.",{ "Нет", "Да!" },onComplete) end,1)     elseif \_G.globallanguage=="pt" then         local do1=performWithDelay(1,function() native.showAlert("Cancelar missão?", "Você realmente quer deixar a missão?",{ "Não!", "Sim!" },onComplete) end,1)     elseif \_G.globallanguage=="tr" then         local do1=performWithDelay(1,function() native.showAlert("Görevi iptal et?", "Görevi terketmek gerçekten istiyor musun?",{ "Hayır!", "Evet!" },onComplete) end,1)     elseif \_G.globallanguage=="ja" then         local do1=performWithDelay(1,function() native.showAlert("あなたは本当にミッションを残したいですか?", "[はい]をクリックします!そして、使命を残します。",{ "まさか", "うん!" },onComplete) end,1)     elseif \_G.globallanguage=="cn" then         local do1=performWithDelay(1,function() native.showAlert("取消任务?", "你真的想离开这个任务吗?",{ "不!", "是的!" },onComplete) end,1)     elseif \_G.globallanguage=="kr" then         local do1=performWithDelay(1,function() native.showAlert("임무를 취소 하시겠습니까?", "정말로 사명을 떠나고 싶니?",{ "안돼!", "예!" },onComplete) end,1)     elseif \_G.globallanguage=="pl" then         local do1=performWithDelay(1,function() native.showAlert("Anulować misję?", "Czy naprawdę chcesz opuścić misję?",{ "Nie!", "Tak!" },onComplete) end,1)     elseif \_G.globallanguage=="cz" then         local do1=performWithDelay(1,function() native.showAlert("Zrušit mise?", "Opravdu chcete opustit misi?",{ "Ne!", "Ano!" },onComplete) end,1)     elseif \_G.globallanguage=="vn" then             local do1=performWithDelay(1,function() native.showAlert("Huỷ nhiệm vụ?", "Bạn có thực sự muốn rời nhiệm vụ?",{ "Không!", "Có!" },onComplete) end,1)     else         local do1=performWithDelay(1,function() native.showAlert("Cancel mission?", "Do you really want to leave the actual mission?",{ "No", "YES!" },onComplete) end,1)     end          --[[    composer.state.nextscene="textscreen"                     func.deleteGraphics()                     \_G.LoadnextsceneFunc ("in")                     --]]      end

The strange part: When now NOT using the native.showAlert and commenting in the last part of the function while commenting out all the native popup code, like shown below… the leak disappears!

Please note this only happens on the device (iPhone6) anyway… and was not a problem on the simulator!

RetryMission = function(Button)     -- checking for bought game:     local file = io.open( \_G.path, "r" )     --[[    -- we first ask if the level should be left and progress lost AND if so, we have to save the current info.. or?     local onComplete=function(event)         -- Handler that gets notified when the alert closes           if ( event.action == "clicked" ) then                 local i = event.index                 if ( i == 1 ) then                     -- Do nothing; dialog will simply dismiss                     -- but we have to move back the button appearance now:                     if Button then                         --Button:setFrame(1)                         Button.y=Button.y-2                     end                 else                                          composer.state.nextscene="textscreen" -- the same "level" is now startd again                     -- save current stats:                     if \_G.generatedZufallsMap==1 or \_G.generatedEndlessTestMap==1 then                         -- do nothing in random map                     else                         loadsave.saveTable(MyLevelUnlockInfo,\_G.levelInfoFileName)                     end                     --composer.state.nextscene="textscreen"                     func.deleteGraphics()                     \_G.LoadnextsceneFunc ("in")                                     end             end      end      -- we check the language and then show the correct texts:           local language = system.getPreference( "locale", "language")     -- new in version 2.3 we aded the timer as local     if \_G.globallanguage=="de" then         local do1=performWithDelay(1,function() native.showAlert("Mission abbrechen?", "Möchtest Du die Mission wirklich verlassen?",{ "Nein", "JA!" },onComplete) end,1)     elseif \_G.globallanguage=="fr" then         local do1=performWithDelay(1,function() native.showAlert("Voulez-vous vraiment quitter la Mission?", "Cliquez sur OUI et quitter la mission.",{ "Non", "OUI!" },onComplete) end,1)     elseif \_G.globallanguage=="it" then         local do1=performWithDelay(1,function() native.showAlert("Vuoi davvero lasciare la missione?", "Fare clic su Sì e lasciare la missione.",{ "No", "Sì!" },onComplete) end,1)     elseif \_G.globallanguage=="es" then         local do1=performWithDelay(1,function() native.showAlert("De verdad quieres salir de la Misión?", "Haga clic en SÍ y dejar la misión.",{ "No", "SÍ!" },onComplete) end,1)     elseif \_G.globallanguage=="no" then         local do1=performWithDelay(1,function() native.showAlert("Avbryt oppdrag?", "Vil du virkelig forlate oppdraget?",{ "Nei!", "Ja!" },onComplete) end,1)     elseif \_G.globallanguage=="nl" then         local do1=performWithDelay(1,function() native.showAlert("Missie annuleren?", "Wil je echt de missie verlaten?",{ "Nee!", "Yes!" },onComplete) end,1)     elseif \_G.globallanguage=="dk" then         local do1=performWithDelay(1,function() native.showAlert("Annuller mission?", "Vil du virkelig forlade missionen?",{ "Nej!", "Ja!" },onComplete) end,1)     elseif \_G.globallanguage=="se" then         local do1=performWithDelay(1,function() native.showAlert("Avbryt uppdrag?", "Vill du verkligen lämna uppdraget?",{ "Nej!", "Yes!" },onComplete) end,1)     elseif \_G.globallanguage=="fi" then         local do1=performWithDelay(1,function() native.showAlert("Peruuta tehtävä?", "Haluatko todella lähteä lähetystyöstä?",{ "Ei!", "Kyllä!" },onComplete) end,1)     elseif \_G.globallanguage=="ru" then         local do1=performWithDelay(1,function() native.showAlert("Вы действительно хотите покинуть миссию?", "Нажмите Да! и оставить миссию.",{ "Нет", "Да!" },onComplete) end,1)     elseif \_G.globallanguage=="pt" then         local do1=performWithDelay(1,function() native.showAlert("Cancelar missão?", "Você realmente quer deixar a missão?",{ "Não!", "Sim!" },onComplete) end,1)     elseif \_G.globallanguage=="tr" then         local do1=performWithDelay(1,function() native.showAlert("Görevi iptal et?", "Görevi terketmek gerçekten istiyor musun?",{ "Hayır!", "Evet!" },onComplete) end,1)     elseif \_G.globallanguage=="ja" then         local do1=performWithDelay(1,function() native.showAlert("あなたは本当にミッションを残したいですか?", "[はい]をクリックします!そして、使命を残します。",{ "まさか", "うん!" },onComplete) end,1)     elseif \_G.globallanguage=="cn" then         local do1=performWithDelay(1,function() native.showAlert("取消任务?", "你真的想离开这个任务吗?",{ "不!", "是的!" },onComplete) end,1)     elseif \_G.globallanguage=="kr" then         local do1=performWithDelay(1,function() native.showAlert("임무를 취소 하시겠습니까?", "정말로 사명을 떠나고 싶니?",{ "안돼!", "예!" },onComplete) end,1)     elseif \_G.globallanguage=="pl" then         local do1=performWithDelay(1,function() native.showAlert("Anulować misję?", "Czy naprawdę chcesz opuścić misję?",{ "Nie!", "Tak!" },onComplete) end,1)     elseif \_G.globallanguage=="cz" then         local do1=performWithDelay(1,function() native.showAlert("Zrušit mise?", "Opravdu chcete opustit misi?",{ "Ne!", "Ano!" },onComplete) end,1)     elseif \_G.globallanguage=="vn" then             local do1=performWithDelay(1,function() native.showAlert("Huỷ nhiệm vụ?", "Bạn có thực sự muốn rời nhiệm vụ?",{ "Không!", "Có!" },onComplete) end,1)     else         local do1=performWithDelay(1,function() native.showAlert("Cancel mission?", "Do you really want to leave the actual mission?",{ "No", "YES!" },onComplete) end,1)     end     --]]          composer.state.nextscene="textscreen"                     func.deleteGraphics()                     \_G.LoadnextsceneFunc ("in")                           end

Do you have an idea why the first function is leaking about 100KB each scene change while the second isn’t?

It all is local and should be removed on device, right? So what is going on here?

Any help welcome!

UPDATE:

More tests show it is happening when using native.showAlert

When not using this the leak is disappearing.

?

Can anyone please give me some hints how to use the native.showAlert with a 100% system memory removal of the used mem? (on device?)

  1. What the heck is this? 
  • If  state  is a table you attached to composer, then you can ignore this comment.

  • If it is a table that composer made and manages, don’t do this.

    composer.state.nextscene=“textscreen”

Reaching into composer.* to modify private data is a BAD BAD BAD idea.

There is no guarantee this will work for future releases and it may cause bugs and/or leaks. 

  • Adding your own logic onto composer is OK (be careful with the variable names you use.
  • Manipulating composer’s internal variables and code is a bad idea.
  1. The problem is not native.showAlert()  it is more likely your wrapper code, or a side-effect of that code above.

  2. That is a very inefficient way to make the language selection code.  It is way too much too read and way too much to maintain.  Leaks could be anywhere in there.  Better to do this:

    – define onComplete before this… local langs = {} – -- langs.shortcode = { title, msg, options } – langs.de = { “Mission abbrechen?”, “Möchtest Du die Mission wirklich verlassen?”, { “Nein”, “JA!” } } langs.fr = { “Voulez-vous vraiment quitter la Mission?”, “Cliquez sur OUI et quitter la mission.”, { “Non”, “OUI!” } } langs.it = { “Vuoi davvero lasciare la missione?”, “Fare clic su Sì e lasciare la missione.”, { “No”, “Sì!” } } … do the rest on your own local function showAlert( currentLanguage ) local d = lang[currentLanguage] – bad variable name, but I did it so code would fit in post if( d ) then local f = function() native.showAlert( d[1], d[2], d[3], onComplete ) end return timer.performWithDelay( 1, f ) end end … now you can use it like this: showAlert(‘fr’)

Updated prior post.

Added more comments and changed tone a bit.

Please note.  I have to opt out of the rest of this discussion if it continues.   I am running out of time for some of my own work.

Tip:  If you don’t resolve this soon, try to find someone experienced who can download your game code and do a code-review.  There are probably some more things they can help you clean up and simplify.

We have two functions for composer:  

composer.setVariable() composer.getVariable()

That does what you’re trying to do by setting a .state table. While I don’t believe we use .state as a composer member it’s not safe in the long term. I know this comes from an old tutorial/recommendation in the Storyboard days, which is why we made a future-proof way to do this using those functions.

Now I’m going to disagree with @roaminggamer here. It’s possible (not probable) that Apple introduced a memory leak with their alerts. Or they changed something and our invocation of native.showAlert() may possibly be leaking with iOS 12+. Since it only happens on device, this is one area where macOS and iOS are executing different code.

This should be easy to prove.  Setup a simple demo app that mimics you changing scenes, showing an alert and changing a scene from within the alert’s handler. You should either see the memory leak or not.

Rob

hi,

my two cents on the subject.

you have established that using the simulator, memory seem to clean up each time, so all seem to be in order. that is good practice and an indication if something is seriously wrong or not. i do the same myself.

however, the simulator runs on a pc or a mac with practically unlimited power and cpu resources, unlike typical devices and their operating systems, which are more tuned for low battery usage, temporary suspension, smoother user experience and so on.

most likely its a os cache and the device will clean it if/when needed.

as long as all works fine, dont worry about it.

Thanks for your fast reply. I now have tested it longer on device to see how much it will add up to…

and right now I’m at 82+ MB system memory usage which is way to high!

I noticed something else strange: around 64MB usage the level animations started to lag and get slow. Moving parts which normally had smooth transitions, stopped a very short time, started to move again a while, then stopped again and so on. Things look to get slower each time I restart the level.

Any idea on this?

that is strange but I still dont know if the memory usage is a problem in itself, however the lagging and slowdown can be an indication that something is happening in the background that isnt good. i’d check that all my objects, sounds, displaygroups and what not are dispatched of properly.

yet, any error/behaviour should show up in the simulator as well so the question is, what do you do programmatically that the simulator is fine with but ios not? do you see the same behaviour on devices running android?

i dont usually develop for ios, so someone with more hands on experience on ios device is needed here.

I still have to run tests for Android.

Is it possible a scene can get called twice maybe? So it loads “doubled”? Then maybe not everything gets removed correctly what was created in this scene. Is such a scenario even possible?

I’m asking because early in development I had a strange bug, where my level code (scene DID phase when everything was on screen) was run twice! I did remove this by adding a check variable but couldn’t find a problem by calling this scene.

Just an idea where I’m starting to look at right now because maybe the scene (composer) handling is different on the simulator and device!?

that something is loading twice, then being removed once, is a good theory for this type of behaviour, and a good place to start.

i dont use scenes, so not very familiar with their inner works.

live game hunting is like amateur hour compared to the sometimes daunting task code bug hunters are challenged with  :smiley:

So it looks it is not the scene call or I did miss something. I have tested all the scene changes with print outputs and everything worked fine.

One other thing could be the admob features which are not supported in the simulator but on device.

Is there something which comes to mind regarding admob maybe? But even if there is a global function or something, this doesn’t explain the size of this strange leak. It’s near 500KB of additonal system memory used everytime I restart the scene.

I now have changed my sound code, so the sounds are loaded only once in main.lua … so this also can’t be the problem.

Graphics should be visible in the texture memory too, right?

So what is left to look at which is handled differently on device compared to the simulator on a Mac?

i dont use ads but i dont think admod would make a mistake, but there is one way to find out. disable it in your app and try and see what happens.

graphics are visible yes.

unless someone else here can specifically give you a ios related hint, i think you are stuck with disabling all parts one by one until you  figure out the culprit, or vice versa, disable all, then enable each part and/or screen step by step, until you figure this out.

sorry i cant be of more help on this