Button Graphics Touch Causes Memory Leak

Hi! I’m completely new to programming, and I have some questions. I have read about display objects, and the “Cleaning Up Display Objects And Event Listeners” tutorial, but I feel like I’m missing something. Whenever I push a button I made, lua memory increases. It keeps increasing every time I push the button, and never decreases again. Here is my code:

[lua]

local function checkMemory()

   collectgarbage( “collect” )

   local memUsage_str = string.format( “MEMORY = %.3f KB”, collectgarbage( “count” ) )

   print( memUsage_str, "TEXTURE = "…(system.getInfo(“textureMemoryUsed”) / (1024 * 1024) ) )

end

timer.performWithDelay( 1000, checkMemory, 0 )

local moveLeftButton

leftButtonPressed = false

function activateUI( event )

   buttonGraphics()

   moveLeftButton:addEventListener( “touch”, touchButtonLeft )

end

function buttonGraphics( event )

   if leftButtonPressed == false then

      moveLeftButton = display.newImage(“images/ButtonLeft.png”)

      moveLeftButton.x = display.contentWidth / 2

      moveLeftButton.y = display.contentHeight / 2

      moveLeftButton.width = display.contentWidth / 5

      moveLeftButton.height = moveLeftButton.width

   else

      moveLeftButton = display.newImage(“images/ButtonLeftPushed.png”)

      moveLeftButton.x = display.contentWidth / 2

      moveLeftButton.y = display.contentHeight / 2

      moveLeftButton.width = display.contentWidth / 5

      moveLeftButton.height = moveLeftButton.width

   end

end

function touchButtonLeft( event )

   if event.phase == “began” then

      leftButtonPressed = true

      buttonGraphics()

   elseif event.phase == “ended” then

      leftButtonPressed = false

      buttonGraphics()

   end

end

activateUI() – this is called from a level module

[/lua]

So, the idea is that I reserve the variable name, draw the graphic once, then check whether or not the graphic is being touch, and if that’s the case, I’m changing it until the button is released. It’s not the .png files being added again and again, as that would increase the texture memory usage. Only lua memory increases. Can anyone tell me what causes the memory leak on button touch? What’s the easiest way to avoid this?

Thanks a bunch!

I think we are going to need to see your “buttonGraphics” function.  We also don’t see where you’re ever removing any thing.  Without that we can’t find your leak.

On a side note you are using globals all over the place. They are prone to cleanup issues and performance problems. It might be helpful to know that Lua is a one pass compiler, where languages like C, C++, C# and so on are two pass. The difference is in a 2 pass system, the first pass, the compiler goes through and determines what all symbols are and the second pass it applies those values.  Thus you can declare a function after it’s used. This is normal for many C programmers who declare their main() function first and then the functions main() calls further down the source file.

Lua is a one pass compiler. When you try to call a value you haven’t created yet, you get “nil”.  Unless of course you’re using globals.  Its normal in Lua to declare functions, tables and variables first then have the code that calls them at the end of the module.  This would allow you to put the “local” keyword in front of your functions and variables to get it behave correctly.

Rob

Hi Rob! Thanks for your reply!

The button graphics function is below the activateUI() function, and above the touchButtonLeft() function. activateUI() is called after I made buttonGraphics(), so it works fine. I made a new program with only this code, to try to find out where the leak is. This is all of the code. Thanks for the feedback on globals.

When I made moveLeftButton local, declared it at the very top of the code, and tried to change the .png inside buttonGraphics, it didn’t override the last one, but added the same image at 0,0. I guess the solution to this would be adding two images, moving them to the same spot, and make one visible or invisible when it is or isn’t touched. But another problem arises because I don’t want it visible from the start of the program. I want to be able to activate it, so declaring it inside a function seemed like the logical thing to do. leftButtonPressed I want to access in another module later. activateUI I also want to access from a different module, so that the button is not on screen until I want it to be. Is there another way to access these, without making them global?

So just to be clear in what I’m trying to achieve, both for people who read this post and myself:

  • Make a button that doesn’t appear until I want it to.
  • Be able to activate the button from potentially several other modules later.
  • Have the button change graphics when interacted with.
  • Have a boolean that is accessible from potentially several other modules that keeps track of whether or not the button is pressed.
  • Do so without causing memory leaks.

Every time you click the button, you are replacing moveLeftButton with a new display object without removing the old one. This is the reason for the memory leak. You need to remove the previous button on each click before replacing it. And since this will be a new display object, you will need to re-add the event listener. Have you tried using widget.newButton() by any chance?

https://docs.coronalabs.com/api/library/widget/newButton.html

That was my initial thought as well, but wouldn’t that mean only the texture memory would increase? The texture memory is static, it’s lua memory that’s increasing. That wouldn’t be the case if the graphics were added again and again, would it? I’ve tried the widget too, and that’s probably what I’ll end up using. I’m just trying to learn different ways of doing tasks at this point.

I don’t really know the finer points of corona and lua, but I’ll give it to you as I understand it:

When you first load a texture, a space is saved for it in memory. If you create multiple objects then that use that same texture, they all use that same location in memory, without having to load it up again. I recall a post recently where someone created an image cache to take advantage of this. They loaded the texture once, and then they could create and destroy objects using that texture over and over without having to load it into memory each time, which I assume is resource-consuming.

As for why lua memory is increasing, a display object is more than just a texture. I think it’s just a table really. So each display object would have to take a place in memory which isn’t freed unless you remove the object. Think of how a display object has x and y coordinates, a rotation, etc. All this has to be stored somewhere.

Ah, that makes sense. Thanks a bunch hasty!

I think we are going to need to see your “buttonGraphics” function.  We also don’t see where you’re ever removing any thing.  Without that we can’t find your leak.

On a side note you are using globals all over the place. They are prone to cleanup issues and performance problems. It might be helpful to know that Lua is a one pass compiler, where languages like C, C++, C# and so on are two pass. The difference is in a 2 pass system, the first pass, the compiler goes through and determines what all symbols are and the second pass it applies those values.  Thus you can declare a function after it’s used. This is normal for many C programmers who declare their main() function first and then the functions main() calls further down the source file.

Lua is a one pass compiler. When you try to call a value you haven’t created yet, you get “nil”.  Unless of course you’re using globals.  Its normal in Lua to declare functions, tables and variables first then have the code that calls them at the end of the module.  This would allow you to put the “local” keyword in front of your functions and variables to get it behave correctly.

Rob

Hi Rob! Thanks for your reply!

The button graphics function is below the activateUI() function, and above the touchButtonLeft() function. activateUI() is called after I made buttonGraphics(), so it works fine. I made a new program with only this code, to try to find out where the leak is. This is all of the code. Thanks for the feedback on globals.

When I made moveLeftButton local, declared it at the very top of the code, and tried to change the .png inside buttonGraphics, it didn’t override the last one, but added the same image at 0,0. I guess the solution to this would be adding two images, moving them to the same spot, and make one visible or invisible when it is or isn’t touched. But another problem arises because I don’t want it visible from the start of the program. I want to be able to activate it, so declaring it inside a function seemed like the logical thing to do. leftButtonPressed I want to access in another module later. activateUI I also want to access from a different module, so that the button is not on screen until I want it to be. Is there another way to access these, without making them global?

So just to be clear in what I’m trying to achieve, both for people who read this post and myself:

  • Make a button that doesn’t appear until I want it to.
  • Be able to activate the button from potentially several other modules later.
  • Have the button change graphics when interacted with.
  • Have a boolean that is accessible from potentially several other modules that keeps track of whether or not the button is pressed.
  • Do so without causing memory leaks.

Every time you click the button, you are replacing moveLeftButton with a new display object without removing the old one. This is the reason for the memory leak. You need to remove the previous button on each click before replacing it. And since this will be a new display object, you will need to re-add the event listener. Have you tried using widget.newButton() by any chance?

https://docs.coronalabs.com/api/library/widget/newButton.html

That was my initial thought as well, but wouldn’t that mean only the texture memory would increase? The texture memory is static, it’s lua memory that’s increasing. That wouldn’t be the case if the graphics were added again and again, would it? I’ve tried the widget too, and that’s probably what I’ll end up using. I’m just trying to learn different ways of doing tasks at this point.

I don’t really know the finer points of corona and lua, but I’ll give it to you as I understand it:

When you first load a texture, a space is saved for it in memory. If you create multiple objects then that use that same texture, they all use that same location in memory, without having to load it up again. I recall a post recently where someone created an image cache to take advantage of this. They loaded the texture once, and then they could create and destroy objects using that texture over and over without having to load it into memory each time, which I assume is resource-consuming.

As for why lua memory is increasing, a display object is more than just a texture. I think it’s just a table really. So each display object would have to take a place in memory which isn’t freed unless you remove the object. Think of how a display object has x and y coordinates, a rotation, etc. All this has to be stored somewhere.

Ah, that makes sense. Thanks a bunch hasty!