Memory Management with display.newImage() is broken!

> 2. You say my version will “likely crash” … NO, it does not crash!

I misread your post.
> c.parent:remove© … is identical to c:removeSelf()

Yes.
> But that will not change the fact that removeSelf() is not documented anywhere in your documentation and is just mentioned once in the Game Edition SDK.

Please file a bug: http://developer.anscamobile.com/content/bug-submission
> In addition… his “c” is not getting freed… the local scope of main.lua is not freed till the program ends …

In GC environments, you must be careful about timing assumptions.

In Corona, the GC system is tiered so that the Lua GC can trigger additional resource cleanup, e.g. graphics resources. However, that add’l cleanup doesn’t happen at the same time as the initial Lua GC; it happens sometime later. Also, Lua’s incremental GC doesn’t immediately cleanup variables, so hitting the end of the main.lua chunk does not imply that local variables get GC’d right away. For a lot of programmers used to non-GC environments (e.g. automatics in C++), the latter can be confusing.

These recent examples do not trigger screen updates. Therefore, Corona doesn’t do the add’l cleanup.

For example, here’s a modified HelloWorld example which is similar to Fogview’s

local background = display.newImage( "world.png" )  
background:removeSelf()  
  
myText = display.newText( "Hello, World!", 10, 80, "MarkerFelt-Thin", 60 )  
myText:setTextColor( 255,180,90 )  

In this example, Lua eventually GC’s the local “background” variable (as there are no more references to it), but it takes awhile since Lua’s GC is incremental. During screen updates, Corona periodically looks for display objects that need to be cleaned up. However, in the above example, the screen is never updated. Therefore, Corona doesn’t perform the clean up.

Here’s a modified version that triggers screen updated by changing the alpha of the text every frame:

local background = display.newImage( “world.png” )
background:removeSelf()

myText = display.newText( "Hello, World!", 10, 80, "MarkerFelt-Thin", 60 )  
myText:setTextColor( 255,180,90 )  
  
local function foo(event)  
 myText.alpha = math.random( 255 ) / 255  
end  
Runtime:addEventListener( "enterFrame", foo )  

In this case, sometime *after* Lua GC’s “background”, Corona will free the underlying display object and release references to graphics resources it is using. Keep in mind, Corona does not immediately free display objects at the same time the corresponding Lua portion is GC’d.
> Correct my OP code and / or file this as bug and correct the SDK!

If you have support issues, please use the “Developer Support” forum.

[import]uid: 26 topic_id: 1251 reply_id: 3492[/import]

@Walter

You seriously ask me to report a bug about yourself mentioning an undocumented member function?

And you ask me to go to developer help for my ironic question to fix my code which illustrates the bug?

And you explain Lua GC will free “local” declared variables of main.lua eventually?

And you tell that in your last example code the display object will be freed at some time?

And you even say that changing of the alpha value will “trigger” screen updates?

… Ich fass es nicht …

No words … [import]uid: 6928 topic_id: 1251 reply_id: 3505[/import]

@walter… to learn something about Corona … Lua and coding…

Try this…

io.output():setvbuf('no')  
  
local background1=display.newImage("test.png")  
background1:removeSelf()  
  
do  
local background2=display.newImage("test.png")  
background2:removeSelf()  
end  
  
collectgarbage("collect")  
print(collectgarbage("count"))  
  
function foo()  
 collectgarbage("collect")  
 print(collectgarbage("count"))  
 print(background1)  
 print(background2)  
end  
  
Runtime:addEventListener("enterFrame", foo);  
collectgarbage("collect")  
print(collectgarbage("count"))  
  

So background1 would suddenly vanish at some time in the future!? [import]uid: 6928 topic_id: 1251 reply_id: 3506[/import]

@Oderwat,

We certainly appreciate your help in trying to test the limits of Corona. However, in this case, I’ve done my best to provide an explanation for why the example in question is not an issue you would worry about in any normal situation. Apps that go on the iTunes store won’t be static. They’ll update the screen all the time, so eventually the resources would be freed (this is equivalent to my changing the alpha every frame). In your test case, the app is static, so it’s not a good indicator of how a real world app would behave. In any real world situation, the resources would be freed.

Ultimately, I’m not sure I understand the issue that’s frustrating you. We’re happy to help, but we need data about how your app operates in the real world. Can you provide more details of the app you are trying to develop and problems you’re seeing in some actual use cases? What exactly is preventing you from making progress on actual apps? [import]uid: 26 topic_id: 1251 reply_id: 3508[/import]

Please take time to read all of my reply…

I am not asking you to explain why this is not problem in and real application.

The whole thing was created because somebody HAD a problem and a question about memory management with his app and I wrote example code to test Coronas behavior.

This was not done to test Coronas limits… It was done to proof a reproducible faulty behavior. Which is usually pretty appreciated by developers worldwide. Usually…

There where also multiple questions asked and most of them did not get an answer or are still what I would call “vague”…

And instead of answers I got explanations which are not even correct or related to the original problem (in my opinion).

My OP code is not static… and none of my other examples have faulty behavior… I made them to explain and proof stuff I said to be right and you stuff to be questionable or wrong explained.

This is the “Bug report” section of the forum… And I reported a reproducible Bug… and documented a lot of its appearance.

My OP sample code does crash the iPhone. Which is a bug … it should never crash (just read that somewhere else). Take it serious! And again… it does not crash the iPod or iPad in my tests.

May I ask you if you EVER tried that code?

There where other people questioning if I maybe do something wrong in that code… Don’t you agree that the code should not crash? Or do you say: Well it may crash because it is out of control of what we can do?

I am not the person which writes programs and think “Well… it seems to work… it must be ok”.

That to say… I am programmer since 1982 and I worked on a lot of different things in the past… for a living… and a good one.

And thank you for your concerns about me making progress in my app. I am doing very good with my current app. And I can assure you that it works pretty well using a lot of “local” variables from main.lua :slight_smile:

It also does not crash on start… Sorry but by “misreading” one of my previous posts and the overall quality of your answers I have to say that I am not satisfied at all with your support.

The only currently known bugs I have in my app… which hold the progress back are such ones as I posted here already:

  1. Text rendering artifacts (major problem… looks ugly and unprofessional to a big degree)
  2. Speed problems with newLine() on the iPhone (not on other devices, had to use rects)
  3. OpenFeint Bug (I am going to post it next)

And open feature requests:

  1. No Device Unique ID accessible
  2. OpenFeint stuff missing (Save Card, Access to Data, User ID / change accessible)
  3. Device Model not available as query

You do not really need to answer on this… You are right: What do I care about anything else than my current app… [import]uid: 6928 topic_id: 1251 reply_id: 3510[/import]

@walter

I think the issue that OderWat talks about is real. I played with his code this morning and changed the display timing and added extra display updates like you mentioned and still see crashes and app shutdown messages in the Console. I’m running my test on a iPhone 3GS with 3.1.3 OS.

The results from running the test program seems very dependent upon what else is “running” on the phone. Even though the IOS 3 doesn’t multitask, there are apps that seem to be running in the background (i.e. Safari, mail, ipod) that affect what happens when the failure occurs.

You mentioned that graphics recovery is done at different times from the Lua GC. You implied that it is done during display updates but that is not what I observed. I added code that displays a text string and changed the alpha value between frames when the image jpegs were being displayed and removed.

My results (using Instruments and Xcode Console) showed that the display images are only removed when a low memory warning message is received. It didn’t matter how often the displayed was updated between the image operations – the amount of memory consumed started around 7 MB and peaked between 36 and 50 MBs before the memory warning kicked in. After the warning message the memory usage dropped down to the 7 MB level.

Your though about it being a race condition seems to be correct. The time when the crash occurred was when the images files were being created and the display memory objects were not freed during a low memory warning (as seen by Safari responding with a Console message). The memory usage continued to grow after the warning message and other apps were asked to shut down. Some times it recovers and once it crashed the app completely. The phone was unstable after that and I had to power-cycle the phone.

I don’t know if this is the intended way that Corona recovers unused display objects, but I would imagine that they should be recovered during display updates (like you implied), which doesn’t seem to be working. From my testing I can’t see any thing the programmer (from the Lua side) can do to force removable of the display object’s memory before getting the low memory warning. OderWat’s code removes the image objects which should free up the memory at some point other than in response to a low memory warning message. Causing extra display updates doesn’t seem to help either.

I also don’t see this as extreme test case for the Corona SDK. One app that I was planning to implement with Corona was a photo viewer. That app would display a large number of photos in a similar way the test app works. Images would be preloaded a few at a time and then removed after viewing. I’m concerned that the memory used by these “removed” images would not be freed until a low memory warning is received. If my app was doing some disk I/o (or something similar), it may not process the memory warning message in time and crash.

This is being posted under “bug report” section on the forum and it does seem like a Corona bug.

-Tom [import]uid: 6119 topic_id: 1251 reply_id: 3538[/import]

These two lines do the same thing?

[code]
currentView:remove(currentView.numChildren)

currentView[currentView.numChildren]:removeSelf()
[/code] [import]uid: 8556 topic_id: 1251 reply_id: 7223[/import]

Yes, it would remove the last display object added to the group “currentView.”

-Tom [import]uid: 7559 topic_id: 1251 reply_id: 7385[/import]

i’m running into similar issues in my ‘real world’ application where it’s freeing up texture memory from a previous page (this is an e-book) then loading assets for a new page. as it’s loading assets for the new page it issues a low memory warning, then in some cases it just crashes and doesn’t free up the texture memory. is there some way to explicitely make corona free up texture memory after i’ve dont removeSelf() on all the graphics from the previous page? thanks! [import]uid: 6317 topic_id: 1251 reply_id: 11929[/import]

For the benefit of this thread: back in Beta 8, we introduced new behavior around removeSelf() which is described here: http://developer.anscamobile.com/content/memory-management-changes-corona-sdk-beta-8

@jwwtaker:

When you call removeSelf(), it does not immediately free the object. You can force Corona to free objects immediately via:

collectgarbage( “collect” )

This forces a Lua GC plus it frees display objects that have been removed and it’s something you can trigger inside a memory warning event. (One caveat: this won’t work inside a hit event listener, e.g. touch events).
[import]uid: 26 topic_id: 1251 reply_id: 11934[/import]

For the sake of the argument, anyone wanting to track *actual* memory leaks in graphic-intensive apps - like games - would probably want to run some GC cycles at runtime, in order to keep Lua garbage at a minumum without running expensive full collection cycles.

Read this for some sample code:

http://developer.anscamobile.com/forum/2010/11/19/how-check-memory-leaks#comment-11727 [import]uid: 5750 topic_id: 1251 reply_id: 12308[/import]