Lua Memory Leak Question

Hi,

First of all, I just want to make sure that my problem is about memory leak. The game crashes at some point without giving any errors in neither logcat nor the Android device.

Let me describe the problem first: ( this is the small part of a game )

1- I start the game app. (~920kb memory)

2- I navigate through the menu, click on How to play menu and then Credits and so on. The memory usage increases at first, but goes back to 920 kb memory when I’m back at the main menu as expected.

3- After that, I want to play the game and press the play button.

4- I watch my first story scene (storyScene1.lua). (When I go back to mainMenu from this scene, the game can free the memory it allocated before. The memory usage in the main Menu is still ~920kb.)

5-When it ends, I changeScene to my second story scene (act1Intro.lua). When the transition is done, my minimum memory usage is increased to ~940 and even if I go back to main menu from that point, I can’t free that allocated memory and see 920 kb ever again in the main menu. 20 kbs of memory is allocated and I can’t free it in anyway.

6- The thing I want to achieve is to start the game after these story scenes(first load, then start playing) but when I do it, I see that my minimum Lua memory usage is increased to ~1080 kb when I return to main menu. 

******** The part that got my attention was that, the minimum allocated memory amount does not increase when I reproduce these steps. When I progress throughout the levels, it keeps increasing like this but when I go back to main menu and restart the game from the 1st level and play all the levels until the one where I left off, the allocated memory amount does not change. It is the latest amount where I returned to main menu. It stays the same as if all these scenes are alive all the time and are not deleted from the memory at all.

I’d be very thankful for any good advice on that matter.

Thank you

(I’m using Director 1.4 by the way.

Corona SDK version 2013.1202.)

Here’s the sample project: 

If you have a complex problem (more than 2 files!) you should create a small self-contained demo of the problem.

It was really hard to get through that code.

I don’t have any of the assets (graphics or sound).

I don’t have a number of the libraries (I have particle candy).

You put it here in the forums where it’s hard to copy-paste. That markup is for easy reading, not massive pastes.

You’re not using storyboard. Director is not a good substitute anymore, in my opinion. The trickery with backbuttonListener and onKeyEvent from main.lua is due to you trying to track all logic paths all the time. This is bug prone, which you know.

You don’t need the backbuttonListener manipulation, you have the onKeyEvent and never get rid of it, so the new listeners may be pointless. I didn’t test much.

The localGroup variables, the cleanup() and createUI methods (onCreate and onDestroy in storyboard!), currentScene/passed!, and timing workaround code are all problems addressed by switching to storyboard. The same as most javascript libraries it comes with the basic tools for UI management. You don’t need a variable for every method to cleanup in storyboard if you stick to static methods (unless you want to declare standalone functions like event handlers)…which leads to leaks I did find.

backButtonListener in storyScene1 does not have a local scope.

particleLoop() in act1Intro does not have a local scope.

Instead of declaring everything at the top (since you’re just declaring it as you go anyway), prefix your definitions with local.

The predeclaration is handy in a storyboard so that you can refer to objects in scene/screen scope when the references would otherwise be lost in an event handler. This duplication is bug prone.

I found no other easy to see problems.

Well, I thought maybe there was something obvious in the code that you’d point out so I didn’t go for a demo but I prepared a demo right now.

I would like to implement Storyboard but this is the project’s ending phase, that’s why I’m looking for a solution with the Director class.

When you run the app, you’ll see that the Lua memory indicator of the Performance Meter is showing that more than 40 KBs of memory is allocated and we can’t get that memory back by any means.

Can you take a look at the demo files and spot what I’m doing wrong?

Thank you

Edit: I moved the sample project to the first message.

I see the increase using my profiler. I am looking into it. Also, I now understand why you try to predeclare everything. It makes it easier to use variables without having to worry about order of declaration.

If I change storyScene1 to go back to the menu:

director:changeScene(“screens.mainMenu”, “crossfade”)

I get a 10k increase. I think there’s 10k in story and intro.

Director stores a reference to each module/screen it encounters, as it leaves that screen. I do not know how to flush that reference, without altering Director. It attempts to call a screen module’s .clean method. I’m not familiar with the way that your screen modules are constructed in your app…how would you export an instance method? I tried renaming cleanUp to clean and Director could not see it so it was never called. Interesting point, I’m using a Graphics 2.0 build, not a legacy build and even using storyboard and doing NOTHING except making a background then backing out, there is a .8k leak that aggregates up to about 3 or 4k then gets collected up. The original increase of .8k * 1 per scene never seems to go away. I’m sorry I couldn’t be more help =(

Thank you for your effort and time :slight_smile:

Did you migrate the sample to Storyboard or am I getting it wrong? If that’s the case, it’s good news that the allocated memory can be set free because right now, I never get the chance to set them free. It’s like every reference is saved in the memory and I’m just pushing values and images into them.

Is there a chance that pre-declaration of variables like what I did is a bad idea in Corona/Lua?

Please keep in mind that there are three or more memory pools in Corona.  The two that we can look at are “Lua memory” and “Texture memory”.  Audio and other things take memory too, but they are not counted in the two above.

Lua memory is represented in kilobytes (k-bytes or thousands) where each k-byte is 1024 bytes of memory.  Your device typically has 256 megabytes of memory (as in millions).  One mega byte of memory is 1024 kbytes.  So your 920 kbytes of memory isn’t even 1 megabyte yet.  Lua memory rarely is the cause of out of memory conditions though it certainly can have leaks and those leaks over time can add up, but if you’re seeing allocations under a megabyte, that shouldn’t be the cause of your memory.

However, leaking texture memory can.  If you print the texture memory, it’s in bytes so you have to divide it by (1024 * 1024) to get it in MB or mega bytes, which is probably the most useful scale to look at it. 

After the OS does it’s thing and other running apps take their memory, you might only have 25-50 mb of memory for your audio, graphics and so on.  Texture memory, or the memory that holds your images, is the biggest consumer of memory.  If you are not freeing up images correctly, you can run out in a real hurry and your app can crash.

Rob

@Rob - We’ve been talking about Lua memory afaik.

@bgmadclown - I did migrate the demo to storyboard, as a test. Predeclaration is handy for procedural code. I have never seen a problem with it, other than failing to synchronize the declaration list and what I actually end up defining.

My point is even if your lua memory gets up to a couple of megabytes, it’s about the impact of one image.

@Rob,

The problem is that, it is under 1 mb just in this demo. During the whole project run, Lua memory is adding up ~100kb of memory every time I change a scene until the point where garbage collector can no longer free any Lua memory. It starts adding up in those scenes that I uploaded and doesn’t add up any memory after I go back to main menu and start all over again like it’s alive all the time. Can you take a look at the sample project?

@jack95,

Can you upload what you’ve done so that it can be a reference for me when migrating?

Here you go. This is only the screens that you gave me. Also, if you profile the migrated demo, you’ll see the leak is much much smaller.

I’m really grateful for your help. I see that the leak is reduced to 10 kb. I’ll try to fully migrate my code to Storyboard as it seems to be working better for me now.

I’ll post the final results here after I tried it out. Still, if there is anyone that can point out the leak with the current code base is much appreciated.

If you have a complex problem (more than 2 files!) you should create a small self-contained demo of the problem.

It was really hard to get through that code.

I don’t have any of the assets (graphics or sound).

I don’t have a number of the libraries (I have particle candy).

You put it here in the forums where it’s hard to copy-paste. That markup is for easy reading, not massive pastes.

You’re not using storyboard. Director is not a good substitute anymore, in my opinion. The trickery with backbuttonListener and onKeyEvent from main.lua is due to you trying to track all logic paths all the time. This is bug prone, which you know.

You don’t need the backbuttonListener manipulation, you have the onKeyEvent and never get rid of it, so the new listeners may be pointless. I didn’t test much.

The localGroup variables, the cleanup() and createUI methods (onCreate and onDestroy in storyboard!), currentScene/passed!, and timing workaround code are all problems addressed by switching to storyboard. The same as most javascript libraries it comes with the basic tools for UI management. You don’t need a variable for every method to cleanup in storyboard if you stick to static methods (unless you want to declare standalone functions like event handlers)…which leads to leaks I did find.

backButtonListener in storyScene1 does not have a local scope.

particleLoop() in act1Intro does not have a local scope.

Instead of declaring everything at the top (since you’re just declaring it as you go anyway), prefix your definitions with local.

The predeclaration is handy in a storyboard so that you can refer to objects in scene/screen scope when the references would otherwise be lost in an event handler. This duplication is bug prone.

I found no other easy to see problems.

Well, I thought maybe there was something obvious in the code that you’d point out so I didn’t go for a demo but I prepared a demo right now.

I would like to implement Storyboard but this is the project’s ending phase, that’s why I’m looking for a solution with the Director class.

When you run the app, you’ll see that the Lua memory indicator of the Performance Meter is showing that more than 40 KBs of memory is allocated and we can’t get that memory back by any means.

Can you take a look at the demo files and spot what I’m doing wrong?

Thank you

Edit: I moved the sample project to the first message.

I see the increase using my profiler. I am looking into it. Also, I now understand why you try to predeclare everything. It makes it easier to use variables without having to worry about order of declaration.

If I change storyScene1 to go back to the menu:

director:changeScene(“screens.mainMenu”, “crossfade”)

I get a 10k increase. I think there’s 10k in story and intro.

Director stores a reference to each module/screen it encounters, as it leaves that screen. I do not know how to flush that reference, without altering Director. It attempts to call a screen module’s .clean method. I’m not familiar with the way that your screen modules are constructed in your app…how would you export an instance method? I tried renaming cleanUp to clean and Director could not see it so it was never called. Interesting point, I’m using a Graphics 2.0 build, not a legacy build and even using storyboard and doing NOTHING except making a background then backing out, there is a .8k leak that aggregates up to about 3 or 4k then gets collected up. The original increase of .8k * 1 per scene never seems to go away. I’m sorry I couldn’t be more help =(

Thank you for your effort and time :slight_smile:

Did you migrate the sample to Storyboard or am I getting it wrong? If that’s the case, it’s good news that the allocated memory can be set free because right now, I never get the chance to set them free. It’s like every reference is saved in the memory and I’m just pushing values and images into them.

Is there a chance that pre-declaration of variables like what I did is a bad idea in Corona/Lua?

Please keep in mind that there are three or more memory pools in Corona.  The two that we can look at are “Lua memory” and “Texture memory”.  Audio and other things take memory too, but they are not counted in the two above.

Lua memory is represented in kilobytes (k-bytes or thousands) where each k-byte is 1024 bytes of memory.  Your device typically has 256 megabytes of memory (as in millions).  One mega byte of memory is 1024 kbytes.  So your 920 kbytes of memory isn’t even 1 megabyte yet.  Lua memory rarely is the cause of out of memory conditions though it certainly can have leaks and those leaks over time can add up, but if you’re seeing allocations under a megabyte, that shouldn’t be the cause of your memory.

However, leaking texture memory can.  If you print the texture memory, it’s in bytes so you have to divide it by (1024 * 1024) to get it in MB or mega bytes, which is probably the most useful scale to look at it. 

After the OS does it’s thing and other running apps take their memory, you might only have 25-50 mb of memory for your audio, graphics and so on.  Texture memory, or the memory that holds your images, is the biggest consumer of memory.  If you are not freeing up images correctly, you can run out in a real hurry and your app can crash.

Rob

@Rob - We’ve been talking about Lua memory afaik.

@bgmadclown - I did migrate the demo to storyboard, as a test. Predeclaration is handy for procedural code. I have never seen a problem with it, other than failing to synchronize the declaration list and what I actually end up defining.

My point is even if your lua memory gets up to a couple of megabytes, it’s about the impact of one image.