Composer Scene Objects - Not removed while we remove the scene from memory

Corona tell us that is you use Composer library , it will automatically handle memory & objects , Every time you design a scene , we keep each of the object in the scene-group [scene.view / self.view].

 

 

Thus this objects are bind with scene group , so as we remove the scene in hide-phase of that scene , all the object with it should also be get clean from memory as they from display.

 

 

I have observed that the objects bind with scene group gets clear only from display but not form memory, we have to manually clean it via using removeSelf().

 

Corona should have a look at composer ,We have to remove each of your scene object Manually in Hide() phase & set that group reference to nil.

 

I am using the following code block to refer the memory leakage in you app/game.

 

[lua]


 

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

Runtime:addEventListener(“enterFrame”, function() collectgarbage(“step”) end)

timer.performWithDelay(2000, printMemUsage, -1)

 

[/lua]

 

 

Assif

You’re probably making a coding error (or an incorrect assumption).  I will help you IF you do the following… 

1.  Create a complete sample project that demonstrates the problem, including (at a minimum) a config.lua, main.lua file, and at least one scene file.

2. Then put that file on drop box or some other safe sharing site (I won’t download it from a site I don’t recognize). 

I will then download it and take a look at what you’re doing and give you feedback to fix it and upload a fixed version to my Free Stuff AskEd repository.

Please Keep It Simple. Just demonstrate the ‘leak’.

-Ed

Ed , I am not a fresher to do such simple mistakes , but yeah sure i will submit a sample scene , & a log file of Memory track.

Through which you can easily get to know about , how if we not remove display object manually while hide phase , they exist in memory .

Assif

  1. I’m asking for a sample because I want to see what assumptions you are making.

  2. This isn’t about your skill as a programmer, so don’t take the prior post the wrong way.  This is more about about understanding how Corona works and assumptions based on your familiarity with Corona.

  • Also everyone makes mistakes.  I’ve been coding for well over 30 years and I make mistakes. (Ask anyone here.)
  • This is why it is best to have another set of ‘eyes’ to examine your code and assumptions.
  • We as programmers and developers are often ‘too close’ to the problem and can’t see the issue because of it.
  1. re: Your last question… If you create content in ‘scene 1’, then from that scene go to ‘scene 2’,
  • ‘scene 1’ and all of its objects will still be in memory.
  • Any code you left running in scene 1 will still be active.
    • timers, enterFrame listeners, other Runtime:* listeners, etc.
  • ‘scene 2’ will now be in memory too.
  • Be aware that composer.* will not ‘delete a scene’ unless it is asked to or a ‘memory shortage’ triggers a delete.
  • Thus, as you implied, if you really want scene content deleted when you exit, the right way to do this is:
    1. Manually purge the scene AFTER you exit. _ - OR - _
    2. Use the will/did show/hide mechanisms for building/destroying content.

Ed, Please dont take it wrong way…

Perhaps , 

  • I am removing display objects & groups

  • I am clearing timers by cancel method

  • I am clearing transitions by cancel method

  • I am making the audio stop & even some time dispose.

  • I am removing the emitters used 

  • At last i am removing the current scene in its did phase of hide event

Anyways , i will forward you the sample project.

No worries on that point.  I simply didn’t answer clearly the first time.

Note:   I would not remove a scene (by calling composer.removeScene()) from within one of its own scene listeners.

If you absolutely must do this, then use a timer with a closure to do the removal.

-- In 'did' phase of 'hide' listener of 'scene1' timer.performWithDelay( 30, function() composer.removeScene( "scene1" ) end )

Ed, 

what does it makes difference , if we remove current scene with timer or without.

If you think , keeping a timer & removing scene after some moment will free memory … No as i observed it via waiting also !!!

And yes i am following the same method, by passing the sceneName in method.

  • If you do it w/o a timer you’re trying to remove something that is currently being used.  That may have unwanted side-effects.

Waiting for your link to example demonstrating the issue.  Can’t respond any more till then.  

Yeah sure , Hope will find a solution for it.

Thanks  Ed

Hi.  I answered a similar question the other day so I just amended my example for that question.

You can download two examples here:

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2016/12/correct_management.zip

  • question1_161216 - Creates and destroys semi-complex content in a scene over and over using will/did mechanisms, then looks for memory leak.
  • question2_161223 - Using create + did hide + removeScene.  Again, looks for leaks.

Warning: To run it directly you will need SSK2 PRO or lite.

However, you can read the code and see what I’ve done. Pay particular attention to scene2.lua.

(Also, this code is easily modified to not use SSK2 if you want to use it for your own example.)

I just ran the  question2_161223  example for 10 iterations with Corona SDK 2016.3001 and observed no leaks.

-Ed

https://www.youtube.com/watch?v=bE1z5n3NphA

Let me chime in here. Composer by default caches scenes so that it’s more efficient the next time you visit it. Hiding the scene does just that, it “hides”’ the scene. It does not “remove” the scene.  That’s the job of the composer.removeScene() function.

scene:create()'s job is to create the objects and put them into a bucket that composer can mange (the scene’s view group)

scene:show()'s job is to execute code when the scene show’s via composer.gotoScene(). Here you start up times and such after the scene is on the screen.

scene:hide()'s job is to execute code when the scene is being hidden (via a composer.gotoScene() call). Here you stop things you started in scene:show().

If you want to clear your memory of the objects, you must call composer.removeScene() to remove those display objects. You do not have to remove them yourself. Just call composer.removeScene(“scenanemtoremove”).  The one gotcha is you can’t remove the scene that’s on the screen.

Rob

I wanted to add more to this too.

When you call composer.gotoScene here is the basic logic:

Does a view for the scene exist? No call scene:create() for the scene

Call the current scene’s scene:hide() will phase.

Call the destination scene’s scene:show() will phase.

Transition the two scenes

Call the now previous scene’s scene:hide() did phase

Call the now current scene’s scene:show() did phase

Then for composer.removeScene():

Call the scene’s scene:destory() function.

Remove all of the display objects for the scene.

Rob

You’re probably making a coding error (or an incorrect assumption).  I will help you IF you do the following… 

1.  Create a complete sample project that demonstrates the problem, including (at a minimum) a config.lua, main.lua file, and at least one scene file.

2. Then put that file on drop box or some other safe sharing site (I won’t download it from a site I don’t recognize). 

I will then download it and take a look at what you’re doing and give you feedback to fix it and upload a fixed version to my Free Stuff AskEd repository.

Please Keep It Simple. Just demonstrate the ‘leak’.

-Ed

Ed , I am not a fresher to do such simple mistakes , but yeah sure i will submit a sample scene , & a log file of Memory track.

Through which you can easily get to know about , how if we not remove display object manually while hide phase , they exist in memory .

Assif

  1. I’m asking for a sample because I want to see what assumptions you are making.

  2. This isn’t about your skill as a programmer, so don’t take the prior post the wrong way.  This is more about about understanding how Corona works and assumptions based on your familiarity with Corona.

  • Also everyone makes mistakes.  I’ve been coding for well over 30 years and I make mistakes. (Ask anyone here.)
  • This is why it is best to have another set of ‘eyes’ to examine your code and assumptions.
  • We as programmers and developers are often ‘too close’ to the problem and can’t see the issue because of it.
  1. re: Your last question… If you create content in ‘scene 1’, then from that scene go to ‘scene 2’,
  • ‘scene 1’ and all of its objects will still be in memory.
  • Any code you left running in scene 1 will still be active.
    • timers, enterFrame listeners, other Runtime:* listeners, etc.
  • ‘scene 2’ will now be in memory too.
  • Be aware that composer.* will not ‘delete a scene’ unless it is asked to or a ‘memory shortage’ triggers a delete.
  • Thus, as you implied, if you really want scene content deleted when you exit, the right way to do this is:
    1. Manually purge the scene AFTER you exit. _ - OR - _
    2. Use the will/did show/hide mechanisms for building/destroying content.

Ed, Please dont take it wrong way…

Perhaps , 

  • I am removing display objects & groups

  • I am clearing timers by cancel method

  • I am clearing transitions by cancel method

  • I am making the audio stop & even some time dispose.

  • I am removing the emitters used 

  • At last i am removing the current scene in its did phase of hide event

Anyways , i will forward you the sample project.

No worries on that point.  I simply didn’t answer clearly the first time.

Note:   I would not remove a scene (by calling composer.removeScene()) from within one of its own scene listeners.

If you absolutely must do this, then use a timer with a closure to do the removal.

-- In 'did' phase of 'hide' listener of 'scene1' timer.performWithDelay( 30, function() composer.removeScene( "scene1" ) end )

Ed, 

what does it makes difference , if we remove current scene with timer or without.

If you think , keeping a timer & removing scene after some moment will free memory … No as i observed it via waiting also !!!

And yes i am following the same method, by passing the sceneName in method.

  • If you do it w/o a timer you’re trying to remove something that is currently being used.  That may have unwanted side-effects.

Waiting for your link to example demonstrating the issue.  Can’t respond any more till then.  

Yeah sure , Hope will find a solution for it.

Thanks  Ed