A leak, or me not getting it.

While playing around with a game, I found that the more I was playing, the more hiccups came up. I thought about a leak, so I searched throughout the code and that the problem was in a pair of function, one that creates an object, one that destroy an object after it reaches a certain point and call the first function again, in a loop.
To be sure nothing else was causing the leak, I just wrote some code from scratch, where some objects are created and the destroyed. I didn’t use an enterFrame function for every object, to avoid any listener mistake or things like that.

local physics = require "physics";  
  
physics.start();  
physics.setGravity(0,0);  
  
local layerObject = display.newGroup();  
  
local function createObject()  
 local object = display.newImageRect(layerAsteroid, "object.png", 64,64);  
 --physics.addBody(object, {density = 5, friction = 2, bounce = 3});  
 object.x = 540  
 object.y = 160  
 --object = nil  
end  
  
local function enterFrame()  
 local num = layerObject.numChildren;  
 for i=num, 1, -1 do  
 local self = layerOBject[i];  
 self.x = self.x-10;  
 if self.done == nil and self.x \<= 420 then  
 self.done = 1;  
 createObject();  
 return true;  
 elseif self.x \<= -50 then  
 self.parent:remove(self)  
 self = nil;  
 return true;  
 end  
 end  
end  
Runtime:addEventListener("enterFrame", enterFrame);  
local function garbagePrinting()  
 print(collectgarbage("count"));  
 print(system.getInfo("textureMemoryUsed"));  
end  
Runtime:addEventListener("enterFrame", garbagePrinting);  
  
collectgarbage("setpause", 50); --this is so that the gc works fast and  
--heavy, letting me see faster if it's leaking or not  
createObject()  

Like it is now, it shows no sign of leaks. The texture memory stay the same, so does the garbage count (after it starts its work). However, if you take out the comment in the line physics.addBody, you’ll see where the leak is. The texture memory stay the same, while the garbage count keeps increasing.
Am I doing something wrong? Is there a way to remove the body that I’m not seeing?
I already mailed Carlos about this, but just wanted to see if anybody has a solution for this :slight_smile: Pretty bugging me. [import]uid: 8486 topic_id: 4715 reply_id: 304715[/import]

Ok, definitely a leak. I searched all over the documentation for a way to remove the body, and it just states that you have to use object:removeSelf();
Plus, the fact that with just the body applied it leaks, and without it doesn’t, means that the code in itself is written properly, without leaks, and that the problem is in the function that removes the body, probably still referencing it somewhere in the lua part, since the texturememory stay the same and only the garbage collect increase.
I’ll wait for a fix (or a solution, or a “you’re doing it wrong! xD”), this is really important to me, since it’s necessary to spawn and delete objects. [import]uid: 8486 topic_id: 4715 reply_id: 15014[/import]

Doesn’t seem to be leaking for me, here’s a the terminal output after I uncomment the addBody line (I added “mem” and “tex” labels just to make the output easier to read):
mem 68.5439453125
tex -1048576
mem 68.5341796875
tex -1048576
mem 68.5439453125
tex -1048576
mem 68.4287109375
tex -1048576
mem 68.6494140625
tex -1048576
mem 68.5146484375
tex -1048576
mem 68.6826171875
tex -1048576
mem 68.5439453125
tex -1048576
mem 68.5341796875
tex -1048576
mem 68.5439453125
tex -1048576
mem 68.4287109375
tex -1048576

There is a cyclical pattern so the memory isn’t the same every time but it does repeat rather than continuously leaking. Notice that the eighth value is back to the third value which is the same as the first value.

Here’s the output with the line commented. The memory consumed is of course a little different, but it’s the same cyclical pattern of memory usage:
mem 68.2880859375
tex -1048576
mem 68.2978515625
tex -1048576
mem 68.1826171875
tex -1048576
mem 68.4033203125
tex -1048576
mem 68.2685546875
tex -1048576
mem 68.3740234375
tex -1048576
mem 68.2978515625
tex -1048576
mem 68.2880859375
tex -1048576
mem 68.2978515625
tex -1048576
mem 68.1826171875
tex -1048576
mem 68.4033203125
tex -1048576

Could you post your results for comparison? Incidentally, thanks for pointing out to me that command collectgarbage(“count”) because I didn’t know about that and it’ll be incredibly useful.

ADDITION: Thanks again for the memory checking code, I just threw that in my own project and noticed a small leak.

http://developer.anscamobile.com/forum/2010/12/12/finding-objects-parent#comment-15181 [import]uid: 12108 topic_id: 4715 reply_id: 15147[/import]

Ok, here’s my output with the line uncommented :

16384
79.9951171875
16384
79.9951171875
16384
79.9951171875
16384
79.9951171875
16384
79.9951171875
16384
79.9951171875
16384
79.9951171875
16384
79.9951171875
16384
80.2099609375
16384
80.3193359375
16384
80.3193359375
16384
80.1044921875
16384
80.1044921875
16384
80.1044921875
16384
80.1044921875
16384
80.1044921875
16384
80.1044921875
16384
80.1044921875
16384
80.1044921875

Here it’s just a 1 point difference but it actually started from 72.
With the line commented, it fluctuates between 69 to 70, never more than that.
The leak is definitely there, or my game would be…acting strange.
I mean, everything goes fine, smoothly, 60 fps rock solid, then after 4-5 minutes, it start to get more and more hiccups.
I checked the whole code, used Instruments on the mac to check for leaks (it shows one leak) and commented out everything until I got what was causing it.
I thought it could be the image but I tried 4-5 images, same results.
[import]uid: 8486 topic_id: 4715 reply_id: 15184[/import]

I just tried the code I posted (I changed it a little while posting it, the names of the variables) and noticed that it was giving me your output, but also a runtime error that was firing only at the start. That’s because in line 9 I left layerAsteroid, it should be layerObject, and also in line 19 there’s layerOBject, with the B, it should have been b.
Did you noticed those? If not, could you change them and try again? [import]uid: 8486 topic_id: 4715 reply_id: 15186[/import]

Okay I just made those changes (don’t you wish you could edit your original post? that’s a really annoying bug in this forum) and retried.

The output when I tried with addBody() commented out was initially confusing because the memory usage just kept creeping up for a while before settling into the following value over and over:

mem 73.1640625
tex -1047552

Then I uncommented the line and the same pattern of increasing memory usage eventually followed by a rapid fall to around 73, only this time after that it crept back up very very slowly. So yeah, I see a tiny memory leak, like an additional 1kb (are the units reported in kilobytes? I read that at some point) used every few seconds.

In my own project linked above I also tracked down leaking memory to addBody lines. Unfortunately I am unable (or at least don’t know how) to see if this leak happens on device too or only affects the simulator.

This may be a bug in Corona that’s simply not been noticed before because the leak is so tiny. [import]uid: 12108 topic_id: 4715 reply_id: 15218[/import]

It goes up by 1, I don’t know if those are kb but it’s not that tiny. The real problem is actually the work of the gc for me. In games, the work that the gc does can bring slowdowns, hiccups and other baaaad things. The more the gc count, the more the work it has to do happens. As I said, my game runs rock solid at 60 fps with a lot of thing spawning (not just 1 kb of leak then, but even more, since there are more things spawning with a body), and I worked really hard on it to be able to manage everything without hiccups or slowdown even on an ipod 2g. After 4-5 minutes, it start to slowdown, and I noticed in the simulator that after 4-5 minutes the leak has got my gc count to 220! Almost doubling what it starts at, 136.
(I also would love to be able to edit first posts :(, I’m glad you found that code useful) [import]uid: 8486 topic_id: 4715 reply_id: 15223[/import]

Is it counting only garbage or total memory usage? I thought it was the latter but I’m not sure about that or the units?

I guess basically can anyone point to good documentation about collectgarbage(“count”) [import]uid: 12108 topic_id: 4715 reply_id: 15226[/import]

I don’t know for sure, but I think that it counts everything that the lua gc could remove. Thus, everything you create adds up to that count, and if you don’t remove it, it stays there. So if, let’s say, I create 5 platform it goes to 60, while running, if there are function or things like that, it goes up for the garbage created from those, and when it starts removing, it goes back to 60, unless I remove those platforms, take out the listeners, nil out the functions, in that case it goes down and down probably to 0.
So basically, I think it’s the amount of memory that the gc think of as “removable”.
But probably some ansca guy can teach us better xD
Haaaaappy new year! [import]uid: 8486 topic_id: 4715 reply_id: 15227[/import]

I get a similar issue: http://developer.anscamobile.com/forum/2010/12/30/memory-leak-touch-listener

I’ve found that mine is caused by the touch listener. My code was originally more like yours, but I was able to remove the Runtime listener and that solved my issue.

The way I was able to remove the runtime listener was by using a transition.to to move and when finished moving oncomplete removed the object. [import]uid: 10903 topic_id: 4715 reply_id: 15266[/import]

Actually your other memory issue I just saw is even more similar to this:
http://developer.anscamobile.com/forum/2010/11/25/memory-leak-issue

Looks like you were having the exact same issue with addBody().

I’d really like someone from Ansca to check if these leaks are real, because I’m suspicious that what we’re seeing is actually some sort of bug with how the numbers are reported. Then obviously if the leaks are real I hope they fix them.

Has anyone sent them an email about this? Maybe just a quick note linking to this thread. [import]uid: 12108 topic_id: 4715 reply_id: 15288[/import]

I already sent a couple of email to carlos, he said he doesn’t have is pc with him for now, so I guess we just have to wait for those holidays to end :smiley:
For me, this is definitely a leak, and not some kind of strange bug. A leak from the lua part (it’s not in texture memory, but in cg count), probably a reference that’s attached when you create a body. [import]uid: 8486 topic_id: 4715 reply_id: 15295[/import]

The latest release of Corona just went up, and I noticed this tucked into the release notes:

Fixed memory leak when using addBody() - case 2153 [import]uid: 12108 topic_id: 4715 reply_id: 32369[/import]

I’ve been using functions cancelAllTimers() and cancelAllTransitions(), in my main.lua that are mentioned in http://blog.anscamobile.com/2011/08/corona-sdk-memory-leak-prevention-101/ They are great functions.

That said, I use director (1.3), and it looks like cleanGroups() was removed from the director class in June 2011. Since I use both cancelAllTimers() and cancelAllTransitions(), maybe I don’t need to worry. But still, I’m not certain if all timers and transitions are being cleaned out when I change scene back from game screen to menu screen.

The flow of my game goes like this:

Starts up on main.lua, which immediately opens menu.lua (no timer or transitions are used in this menu).

Then game screen is accessible from menu.lua – there are number of timers and transitions that are triggered during the game session. The game uses physics engine. In the game, I consistently use the method mentioned in http://blog.anscamobile.com/2011/08/corona-sdk-memory-leak-prevention-101/ (i.e., timerStash.newTimer = timer.performWithDelay( … and transitionStash.newTransition = transition.to( myObject { …

When back-to-menu button is clicked from the game lua, I call both cancelAllTimers() and cancelAllTransitions() before director:changeScene(event.target.scene, “crossfade”) is called.

However, when the screen changes back from game screen to menu screen, the MemUsage doesn’t go back to what it was the first time menu.lua was loaded. Is this normal?

I use the terminal print out to watch the memory usage with the following code:

\>\> hit the last line of XXXX.lua  
collectgarbage()  
print( "MemUsage (in KB): " .. collectgarbage("count") )  
system.getInfo( "textureMemoryUsed" )  
print( "textureMemoryUsed is " .. system.getInfo( "textureMemoryUsed" ) )  

The above code is inserted before the display group is returned for director.

And here’s the terminal print out of the MemUsage:

Step 1) Immediately after main.lua is launched
>> hit the last line of MENU.lua
MemUsage (in KB): 121.2939453125
textureMemoryUsed is 1210368

Step 2) game screen is accessed from menu.lua
>> hit the line before return game1Group of GAME1.lua
MemUsage (in KB): 285.8388671875
textureMemoryUsed is 4052992

Step 3) go back to menu screen from game screen
>> hit the last line of MENU.lua
MemUsage (in KB): 286.0498046875
textureMemoryUsed is 4052992

Step 4) from menu.lua access options.lua – currently there’s only one button in options.lua clicking on it will send me back to main.lua
>> hit the last line of OPTIONS.lua reached
MemUsage (in KB): 286.919921875
textureMemoryUsed is 2795520

Step 5) Here’s what I see when I return to menu.lua
>> hit the last line of MENU.lua
MemUsage (in KB): 286.9169921875
textureMemoryUsed is 2795520

Notice how in Step 1, MemUsage was only 121KB. But after accessing the game screen, MemUsage is up to 285KB to 286KB range. Is this normal?

I also have play again button inside the game screen, and when I hit play again button a few times (without really playing the game at all, but simply reloading the game screen, which means no timers and transitions are launched during the game session) and return to menu.lua, the MemUsage goes up to 291KB. Can this be normal? If I play the game and return to menu.lua, MemUsage goes up to 319KB.

It feels like MemUsage should always go back to 121KB and textureMemory to somewhere around 1MB because that’s what I get when I first access menu.lua – but somehow, it never goes down to that range.

I’ve been puzzling over this too long and I thought maybe someone can shed some light…

[import]uid: 67217 topic_id: 4715 reply_id: 51424[/import]

@ask: The best thing you can do is just go through your code and check to make sure that you are removing everything correctly (as well as stopping all timers and transitions).

I believe the later versions of the Director class allow you to call some kind of clean function which gets called after the screen transitions, to ensure all of your objects/timers/transitions, etc. were all cleaned up.

If you do that and are STILL experiencing memory leak issues, then I would suggest you put together a smaller project with fewer images, that switches screens in the exact same manner as your app does to see if memory is still climbing. If it is, then you could have found a memory leak in the core, in which case you should submit a bug (along with that test project) so the engineers here can have a look at some of the internals to try and pinpoint what’s causing the memory usage to go up and up. [import]uid: 52430 topic_id: 4715 reply_id: 51426[/import]

Thank you, Jonathan, for getting back to me.

Here’s the thing. I have three buttons on my menu.lua right now:

Play Game
Levels
Options

Play Game accesses the game1.lua
Levels accesses the levels.lua
Options accesses the options.lua

Nothing much is going on with levels.lua and options.lua:

levels.lua has four buttons clicking on which will simply changes the scene, and one of the button sends me back to menu.lua

options.lua has one button, clicking on which will simply change the scene back to menu.lua

So, I moved from screen to screen in the following order:

menu.lua
options.lua
menu.lua
levels.lua
menu.lua
levels.lua
menu.lua
options.lua
menu.lua

As you can see, I did not access game lua. And here’s the memory usage terminal print out. And… MemUsage simply goes up:

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit the last line of MENU.lua
MemUsage (in KB): 121.2939453125
textureMemoryUsed is 1210368
>>>>> hit the last line of the MAIN lua code
MemUsage (in KB): 120.6689453125
textureMemoryUsed is 1210368
>>>>> hit the last line of OPTIONS.lua reached
MemUsage (in KB): 124.9560546875
textureMemoryUsed is 1222656
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit the last line of MENU.lua
MemUsage (in KB): 125.171875
textureMemoryUsed is 1222656
>>>>> hit the last line of LEVELS.lua reached
MemUsage (in KB): 154.59765625
textureMemoryUsed is 1253376
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit the last line of MENU.lua
MemUsage (in KB): 153.3388671875
textureMemoryUsed is 1253376
>>>>> hit the last line of LEVELS.lua reached
MemUsage (in KB): 155.23046875
textureMemoryUsed is 1253376
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit the last line of MENU.lua
MemUsage (in KB): 152.5498046875
textureMemoryUsed is 1253376
>>>>> hit the last line of OPTIONS.lua reached
MemUsage (in KB): 146.330078125
textureMemoryUsed is 1222656
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit the last line of MENU.lua
MemUsage (in KB): 146.3271484375
textureMemoryUsed is 1222656

Notice I don’t use the runtime event listener to monitor the memory usage. Could it be that it takes time for the system to clean out – i.e., it doesn’t release the memory the instant collectgarbage() is called, but maybe there’s some delay? Or… Are we seeing a memory leak in the core?

Naomi

[import]uid: 67217 topic_id: 4715 reply_id: 51429[/import]

Do me a favor, and wrap your calls to collectgarbage() in a 1 millisecond delay, like so:

[blockcode]
timer.performWithDelay( 1, function() collectgarbage(); end, 1)
[/blockcode]

Not likely that will make much of a difference, but let’s try it anyway before going further. [import]uid: 52430 topic_id: 4715 reply_id: 51433[/import]

I replaced collectgarbage() with what you provided above, like this:

print( "\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\> hit the last line of MENU.lua" )  
--collectgarbage()  
timer.performWithDelay( 1, function() collectgarbage(); end, 1)  
print( "MemUsage (in KB): " .. collectgarbage("count") )  
system.getInfo( "textureMemoryUsed" )  
print( "textureMemoryUsed is " .. system.getInfo( "textureMemoryUsed" ) )  

And I did the same with levels.lua and options.lua, and then went through the screens in the same order as before. And here’s what I see on the terminal. Maybe the wrapped timer needs to be removed somehow? The number is climbing…

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit the last line of MENU.lua
MemUsage (in KB): 128.5517578125
textureMemoryUsed is 1210368
>>>>> hit the last line of the MAIN lua code
MemUsage (in KB): 121.0322265625
textureMemoryUsed is 1210368
>>>>> hit the last line of OPTIONS.lua reached
MemUsage (in KB): 140.234375
textureMemoryUsed is 1222656
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit the last line of MENU.lua
MemUsage (in KB): 139.3935546875
textureMemoryUsed is 1222656
>>>>> hit the last line of LEVELS.lua reached
MemUsage (in KB): 172.40625
textureMemoryUsed is 1253376
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit the last line of MENU.lua
MemUsage (in KB): 172.501953125
textureMemoryUsed is 1253376
>>>>> hit the last line of LEVELS.lua reached
MemUsage (in KB): 178.107421875
textureMemoryUsed is 1253376
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit the last line of MENU.lua
MemUsage (in KB): 174.7900390625
textureMemoryUsed is 1253376
>>>>> hit the last line of OPTIONS.lua reached
MemUsage (in KB): 165.126953125
textureMemoryUsed is 1222656
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit the last line of MENU.lua
MemUsage (in KB): 166.162109375
textureMemoryUsed is 1222656
[import]uid: 67217 topic_id: 4715 reply_id: 51435[/import]

BTW, I’m using Corona SDK on Mac OS X Build 2011.591 (because I had trouble with InMobi banner ads with the CoronaSDK 2011.605) [import]uid: 67217 topic_id: 4715 reply_id: 51437[/import]

I know this is probably more than you want to do, but I would try creating a blank project with director, with three different screens. Each screen will display a different image, and that’s it. No timers or transitions. Then, try transitioning between the screens (with a button, perhaps) and see if memory keeps climbing… [import]uid: 52430 topic_id: 4715 reply_id: 51488[/import]