Memory problems using director class

14 replies [Last post]
mykyl66
User offline. Last seen 8 years 29 weeks ago. Offline
Joined: 12 Oct 2010

Hi,

I am using the director class for a couple of test games. Both suffer from the same issue of memory usage going up and up regardless of what I do.

While playing a level the memory usage is stable. No weird changes and things work as expected.

I have a cleanup function that clears all all the timers and listener events and anything else that I can find. I have a button that takes the player back to the level selection screen and the last thing that it it does is report the system memory.

If I re-choose the level and then exit again the system memory use will be around 3kb to 4kb more. If I exit then go back again, once again the memory will be a further 3 to 4 kb more.

The following code is what is being called before going back to the level select screen.

Any tips on what I might be missing?

I basically just want the entire level and all objects gone but something still seems to be in memory and not being cleared.

Thanks

Mike R

local function cleanup()
timer:cancel(createIt)
background:removeEventListener( "touch",createIt)
Runtime:removeEventListener("enterFrame",checkIt)
Runtime:removeEventListener("collision",pinIt)
_G.loadObjectGroup:removeSelf()
textGroup:removeSelf()
savedGroup:removeSelf()
createIt = nil
background = nil
_G.loadObjectGroup = nil
textGroup = nil
savedGroup = nil
allIts = nil
collectgarbage("collect")
print (sprite )
end

local function backToLevelList(event)
gameActive = false
physics.pause()
cleanup()
physics.stop()
exitLevel:removeEventListener("touch",backToLevelList)
exitLevel = nil
levels = nil
print("System Memory : " .. collectgarbage("count"))
director:changeScene("levelSelect","fade",true)
end

Replies

mykyl66
User offline. Last seen 8 years 29 weeks ago. Offline
Joined: 12 Oct 2010

I'm guessing it doesn't matter anyway.
While it works as a system in the simulator it fails to load any levels on the actual device. Literally nothing happens. No idea why as it all worked before.

Mad.

Mike R

ricardorauber
User offline. Last seen 3 years 11 weeks ago. Offline
Joined: 30 Aug 2010

This is not because of Director, it's something from Corona itself. Director just loads other files and try to unload when change the scene. Maybe something is missing but it's hard to get everything to clean up dynamically.

There's an issue with some images that I can't explain why it happens but works fine in the simulator and crash in the device. I always use Adobe Fireworks to create my images or export to 24-png in Photoshop. All other types of images makes device crash with low memory.

mykyl66
User offline. Last seen 8 years 29 weeks ago. Offline
Joined: 12 Oct 2010

I read about issues regarding corona not clearing out memory properly with some images but it was so long ago and we have had two updates since ten I thought they would have fixed that issue by now???

I converted all my images to 24-png and it made no difference to the memory usage.

I just thought there might be a system to make sure you have cleared everything else that the director class cannot. e.g. transitions, event listeners and global variables. Are these the only items the director class cannot auto remove?

Just tried again to install a new build to my ipod touch and still have the issue that levels no longer get loaded up. Nothing happens at all. It doesn't crash or anything.

The code that I am running is the following. the last button works as before but nothing I do can get a level to work on the device even though it works fine in the simulator.

There are no crashes ever.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
local bt01 = display.newImage("level1.png")
        local function bt01t ( event )
                if event.phase == "ended" then
                _G.currentLevel = 1
                        director:changeScene("game","fade")
                end
        end
        bt01:addEventListener("touch",bt01t)
        bt01.x = 160
        bt01.y = 200
        localGroup:insert(bt01)
        --
        local bt02 = display.newImage("level2.png")
        local function bt02t ( event )
                if event.phase == "ended" then
                _G.currentLevel = 2
                        director:changeScene("game","fade")
                end
        end
        bt02:addEventListener("touch",bt02t)
        bt02.x = 160
        bt02.y = 260
        localGroup:insert(bt02)
        --
        local bt03 = display.newImage("level2.png")
        local function bt03t ( event )
                if event.phase == "ended" then
                        _G.currentLevel = 3
                        director:changeScene("game","fade")
                end
        end
        bt03:addEventListener("touch",bt03t)
        bt03.x = 160
        bt03.y = 320
        localGroup:insert(bt03)
        --
        local bt04 = display.newImage("closebtn.png")
        local function bt04t ( event )
                if event.phase == "ended" then
                        director:changeScene("mainmenu","fade")
                end
        end
        bt04:addEventListener("touch",bt04t)
        bt04.x = 160
        bt04.y = 380
        localGroup:insert(bt04)<code>
 
Thanks
 
Mike R

ricardorauber
User offline. Last seen 3 years 11 weeks ago. Offline
Joined: 30 Aug 2010

Mike,

For now, Director can remove all display objects inserted into the localGroups and the listeners added to them. All timers, transitions and runtime listeners must be stopped/removed by your cleanup function.

mykyl66
User offline. Last seen 8 years 29 weeks ago. Offline
Joined: 12 Oct 2010

That's what I thought. I guess I need to chase up the Ansca folks and see what they are doing about the memory problems as it is obviously not fixed yet.

Cheers

Mike R

mykyl66
User offline. Last seen 8 years 29 weeks ago. Offline
Joined: 12 Oct 2010

Just wanted toa dd that the working on the device issue was caused by an uppercase mistake. So it seems that the corona simulator doesn't care if an item is upper case or lower case when requesting a file yet the ios device and xcode simulator do.

I have sent a message to the ansca folks and hope they sort it as because there were no errors generated at all and I had no idea where the problem was in my code, it took about 8 hours to figure out I needed an upper case D in the word Data on one blasted line of code. :)

Cheers

Mike R

ricardorauber
User offline. Last seen 3 years 11 weeks ago. Offline
Joined: 30 Aug 2010

Thanks Mike, that's really important to know!

jonbeebe
User offline. Last seen 6 years 44 weeks ago. Offline
Joined: 26 Jul 2010

Any word on this:

"If I re-choose the level and then exit again the system memory use will be around 3kb to 4kb more"

I'm experiencing the SAME issue, though with some scenes, the memory goes up WAY more than 3kb to 4kb, and it just keeps climbing.

I've made sure that EVERYTHING is cleaned up from the previous scene (timers, transitions, display objects AND groups). In fact, texture memory is stable and is what I would expect from everything being cleaned up properly.

However, the memory usage (provided by collectgarbage("count") ) continues to climb, though like you said, mainly when switching to different scenes. I'm not using Director for this particular project, though I am using an internal script of my own that works very similarly.

This is even the case with scenes that have relatively few objects, timers, etc. where it is VERY easy to see that I am clearing everything out properly. It has to be a Corona bug...

charlyp
User offline. Last seen 24 weeks 5 days ago. Offline
Joined: 19 Feb 2010

Well, I have quite the same problem using Director.

I've read all the threads (ancient and recent) about memory leaks and Director's cleaning function, I tried (successfully) to optimize my code but I still get a memory leak when I change scene: the GC count climbs up around 4 (the GC count is "collected"just before displaying it). Is that a "big" leak?
By the way, I don't know what exactly this "count" refers to; is it KB? number of objects? something else? Jonbeebe mentions 3-4kb. Is that it?

Also, I was wondering if local tables need to be emptied before getting "niled" themselves in order for the memory to be released or if it'll be done automatically like any other local variable? And what about sounds? I do all that, I clean everything I can --the texture memory is perfectly stable, by the way--, but it seems rather strange to have to "nil" things declared as "locals".

Don't misunderstand me, I like Corona very much and I plan on creating a lot of apps with it =)

Thanks for your help.
Ch.

mykyl66
User offline. Last seen 8 years 29 weeks ago. Offline
Joined: 12 Oct 2010

It does get a bit frustrating. Its the usual, "am I doing something wrong or is it a bug in Corona".

My current game is 13 kb every single change of scene whether the same scene or new scene.

Someone else I know has exactly the same 13 kb increase each time as well.

Like other here I have experimented trying to nail down what was causing the issue. I have nilled all tables etc trying to find what is causing this silly little issue.

I really hope that someone can nail it down at some point.

Oh by the way, like you folks, my texture memory is rock solid.

Cheers

Mike R

jonbeebe
User offline. Last seen 6 years 44 weeks ago. Offline
Joined: 26 Jul 2010

Try using this, more efficient version of Director Class:

http://developer.anscamobile.com/forum/2011/03/06/director-class-12-more-efficient-cleangroups-function

It's the same (v1.2), however, it replaces the cleanGroups() function with a more efficient one, and adds a few lines elsewhere in the module that's needed to work with the modified cleanGroups() function (which is just recreating a group after it's been 'cleaned', because this new function will completely nil it out).

This has helped my projects out tremendously (the one's where I show a leak of a few kb here and there and never going back down, as you described).

Also, another thing to know when using the Director class IF you are using ui.lua.

You should be sure to forward address all of your UI buttons, and then when you go to change a scene with Director class, you MUST remove all the touch listeners on your ui buttons or they will hold onto a reference even after your buttons have been removed. This can and will lead to crashes later on in your app (or even immediately).

So for example, let's say you have a UI button (made with ui.lua) called 'myButton'...

Before you call changeScene(), you should call another function that will remove the touch listeners from all of your ui buttons, like so:

1
2
3
4
5
local removeListeners = function()
    if myButton then
        myButton:removeEventListener( "touch", myButton )
    end
end

And so on...

Alternatively, if you don't want to use the modified Director class... you can use a module I recently posted to my blog that will actually replace the built-in display.newGroups() and give you a separate cleanGroup() function for more efficient group-cleaning:

http://jonbeebe.tumblr.com/post/3760389212/proper-group-cleaning-in-corona-script-download

Hope that helps!

charlyp
User offline. Last seen 24 weeks 5 days ago. Offline
Joined: 19 Feb 2010

Hey Jonbeebe,

Actually, I'm already using your modified version of the Director class =) Thanx for that!

About removing the listeners for each UI button, why isn't it done by Director like all other images+listeners manually created if I insert the UI buttons into the localGroup after they've been created?
I don't doubt what you're saying, eh, I just would like to understand why this is different ;)

By the way, I've posted a question about a similar problem with movieclips and Director in a different thread but got no answer so far; are you aware of that? Is it a known issue or did I just miss something?

Thanks for you help.
Ch.

jonbeebe
User offline. Last seen 6 years 44 weeks ago. Offline
Joined: 26 Jul 2010

While there are times when event listeners attached to display objects are removed with the objects themselves, there are some cases where listeners may be called when the object is gone and that could generate an asset error. This would be true if there was a reference to the display object within the listener and the listener did not test to see if the display object was removed.

In regards to this issue, Tom from Ansca put it best:

"Best practices would be to 1) remove the listener, 2) removeSelf the
display object, and 3) set the object to nil."

Also keep in mind that enterFrame listeners are attached to Runtime so they must *always* be removed manually.

---

Regarding the other thread, I have not seen it, but will go check it out now...

jonbeebe
User offline. Last seen 6 years 44 weeks ago. Offline
Joined: 26 Jul 2010

Tom sheds more light on this issue in his comment in this thread:

http://developer.anscamobile.com/forum/2011/03/06/remove-all-objects#comment-27365

Viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.