Frame rate drops to half after about a minute of play?

Hi all;

I have a problem I’ve been trying to solve for the past 3 or four days. When I play my app everything is fine until about a minute into the play the frame rate drops to about half or 15FPS - and doesn’t come up again until I switch scenes.  I understand this is probably due to a memory leak and I have looked at and followed this post:

http://forums.coronalabs.com/topic/22091-guide-findingsolving-memory-leaks/

However, it’s still doing it.

I am completely stumped. The app is a slot type app and every time I hit spin it works fine but like i said the frame rate drops after about a minute of play. I commented out all audio, I nulled out any and all timers, transitions, listeners and images/objects that are no longer in use, and it still does it. I’m using daily build 2014.2288.

I don’t know what else to do, any help would be greatly appreciated.

Cheers.

Without seeing some code, people are probably not going to be able to give you any better advice than what’s in that forum post.  You can add some prints and watch your console log.  Perhaps you’re adding some runtime listeners over and over.  Print out your memory usage and see what memory foot print you’re using.  Its very possible that you might not have a leak, but that you’re using a lot of memory anyway.

Rob

Hi Rob;

Thanks for the reply. I figured without looking at the code it would be hard for anyone to help. I have checked the runtime listeners and for each instance of adding one I remove it when the function is done / animation is complete, etc.

The app is using about 3.5 MB LUA memory and 45MB Texture memory on the iPad retina in corona simulator according to the performance meter I found on this forum - sorry I don’t have the link any more.

The memory is constantly increasing and then after about 20 seconds or so it goes back down to the level it started at. I don’t know if that is normal memory behaviour or not - however when I run just the performance meter in an “empty” app it does the same thing only the climbing is slower.

Anyway, that’s actually an answer for me - I was wondering if perhaps it simply uses too much memory or maybe there is just way too much going on when I hit spin or when it’s finished spinning with all of the win animations and sounds etc…

How do  I do this? “Print out your memory usage and see what memory foot print you’re using.” Is there a way to see what is actually using how much memory while the app is running? That would be awesome if I could see that - for instance - how much memory the listeners are using, or the images etc. and how it changes as I do things in the app. LOL maybe a tall order? I don;t know.

Cheers!

Oh yeah one more question for now. Is it better to pre-load audio and then simply play it? or is it better to load play dispose all when you want to play a sound?

The reason I ask is I notice the frame rate drops significantly at the end of the spin cycle on the app when the audio plays then when it is done playing it goes back up a bit, but never back to 30FPS after about 10 spins. LOL Wow confusing.

Cheers!

The storyboard library (though we are deprecating it) has a storyboard.printMemUsage() API Call.  See: 

http://docs.coronalabs.com/api/library/storyboard/printMemUsage.html

It’s basically showing the results of system.getInfo(“textureMemoryUsed”) and collectgarbage(“count”).  Now the collectgarbage() returns memory in Kbytes.  The system.getInfo() returns it in bytes. 

Yes, it is normal for memory to go up and down.  If it goes up by 20 then down by 10 and up by 20 then down by 10 you probably have a leak.

As for the audio question, it’s a balance.  Loaded audio takes up memory.  Larger tracks take up more than smaller tracks.  44khz stereo tracks take up more memory than 11khz mono tracks.  But large tracks take time to load (though we do have audio.loadStream() which helps hide the delay of loading.   I personally would make sure my sound files are as small as I can get them.  Load sounds you will use over and over at the beginning and keep them around. Things only needed for the scene should probably be loaded in the createScene() and disposed in destoryScene().

OK great thanks for the replies. I jus wasn’t sure if it could just be from memory usage (e.g. the system has too much going on perhaps?).

Cheers.

OK so I thought I had the problem solved yesterday, unfortunately not.

I have narrowed the source or cause of the issue to one big (huge?) function in my code, when I comment it out the problem seems to go away. The frame rate does;t drop as drastically ( about 2 or 3 FPS per 60 plays / cycles as opposed to half after 10 plays or cycles as it was before).

So heres a dumb newbie type question for you…

Is it better for performance sake to split this large function into a bunch of smaller functions? Perhaps even make it into a completely separate  module? Would that make a large impact on performance?

I’m hoping that is the case and I am about to embark on this endeavour… I will report back soon.

Any help/comments would be greatly appreciated.

Cheers!

I guess a lot would depend on what you’re doing ni that large function.  If you’re still executing 1000 instructions, it doesn’t really matter how you break it up.  You probably should spend more energy finding out why the function is taking up so much time.

From a purely ability to support your code, long functions are hard to read, hard to trouble shoot and slow to edit (think about how much scrolling up and down you do in your editor).  You will be best to break it down for your own sanity.  Now you might find your performance problem by breaking things down.  You can find problems that way.

Rob

Yes, sanity is crucial. Lol Ok thank you again. I appreciate the info. I will post how I make out. Cheers Rob.

Hi.

OK so I have finally narrowed it down to a custom function I wrote to add a stroke to some text objects, players coin balance for example. (Is there a better way or an API for this? I tried textObject.strokeWidth etc. however it looks funny when it renders it on screen, the text stroke is all lumpy and looks bad). 

Anyway, the function is called several times per second sometimes (when the balance is incremented after a win for example. I assume the nilling out of the stroke objects worked however maybe I have to also nil out the text object itself each cycle? Not quite sure.

Here is the function I wrote: (sometimes it is called on each frame for about up to 40 or so frames - therein lies the performance issue I believe!)

function strokeText(target,strokeColor,strokeWidth, textSize)

–[[

display.remove(target.strokeBack1) --This is the same as calling object:removeSelf(), but will first check if the object exists before attempting to remove.

display.remove(target.strokeBack2)

display.remove(target.strokeBack3)

display.remove(target.strokeBack4)

display.remove(target.strokeBack5)

display.remove(target.strokeBack6)

display.remove(target.strokeBack7)

display.remove(target.strokeBack8)

target.strokeBack1 = nil target.strokeBack2  = nil target.strokeBack3  = nil target.strokeBack4  = nil target.strokeBack5  = nil 

target.strokeBack6  = nil target.strokeBack7  = nil target.strokeBack8  = nil 

– if target.strokeBack1 ~= nil then target.strokeBack1:removeSelf() target.strokeBack1 = nil end

– if target.strokeBack2 ~= nil then target.strokeBack2:removeSelf() target.strokeBack2  = nil end

– if target.strokeBack3 ~= nil then target.strokeBack3:removeSelf() target.strokeBack3  = nil end

– if target.strokeBack4 ~= nil then target.strokeBack4:removeSelf() target.strokeBack4  = nil end

– if target.strokeBack5 ~= nil then target.strokeBack5:removeSelf() target.strokeBack5  = nil end

– if target.strokeBack6 ~= nil then target.strokeBack6:removeSelf() target.strokeBack6  = nil end

– if target.strokeBack7 ~= nil then target.strokeBack7:removeSelf() target.strokeBack7  = nil end

– if target.strokeBack8 ~= nil then target.strokeBack8:removeSelf() target.strokeBack8  = nil end

local offset1 = strokeWidth

–local offset2 = offset1

target.strokeBack1 = display.newText(target.parent,target.text,target.x+offset1, target.y+offset1,fontStyle,textSize)

target.strokeBack1:setFillColor(unpack(strokeColor))

target.strokeBack1:toFront()

target.strokeBack2 = display.newText(target.parent,target.text,target.x-offset1, target.y-offset1,fontStyle,textSize)

target.strokeBack2:setFillColor(unpack(strokeColor))

target.strokeBack2:toFront()

target.strokeBack3 = display.newText(target.parent,target.text,target.x+offset1, target.y-offset1,fontStyle,textSize)

target.strokeBack3:setFillColor(unpack(strokeColor))

target.strokeBack3:toFront()

target.strokeBack4 = display.newText(target.parent,target.text,target.x-offset1, target.y+offset1,fontStyle,textSize)

target.strokeBack4:setFillColor(unpack(strokeColor))

target.strokeBack4:toFront()

target.strokeBack5 = display.newText(target.parent,target.text,target.x, target.y+offset1,fontStyle,textSize)

target.strokeBack5:setFillColor(unpack(strokeColor))

target.strokeBack5:toFront()

target.strokeBack6 = display.newText(target.parent,target.text,target.x, target.y-offset1,fontStyle,textSize)

target.strokeBack6:setFillColor(unpack(strokeColor))

target.strokeBack6:toFront()

target.strokeBack7 = display.newText(target.parent,target.text,target.x-offset1, target.y,fontStyle,textSize)

target.strokeBack7:setFillColor(unpack(strokeColor))

target.strokeBack7:toFront()

target.strokeBack8 = display.newText(target.parent,target.text,target.x+offset1, target.y,fontStyle,textSize)

target.strokeBack8:setFillColor(unpack(strokeColor))

target.strokeBack8:toFront()

target:toFront()

return target.strokeBack1, target.strokeBack2, target.strokeBack3, target.strokeBack4, target.strokeBack5, target.strokeBack6, target.strokeBack7, target.strokeBack8

–]]

–print(“stroke text”)

–return true

end

There’s probably a better way to do this but that’s what I came up with so far… LOL

Do I need to pass in the text object and then nil out the original text object or is this just going to always mess up the performance and I should just avoid the text stroke?

What about something like target = nil  and then target.text = “textPassedIn” ?

I don;t know.

I appreciate all your help.

Cheers!

Generating Text objects is an expensive process.  You can’t stroke our text with normal techniques because we are rendering a graphical rectangle.  I would suggest considering using a bitmap font.  There are a couple of different libraries out there, one created by one of our own Community Members.  See:  http://forums.coronalabs.com/topic/46506-bmglyph-and-bitmap-font-for-graphics-20/?hl=%2Bbitmap+%2Bfont

Maybe that would render better.

Rob

Ok great I will check it out. Cheers Rob.

Without seeing some code, people are probably not going to be able to give you any better advice than what’s in that forum post.  You can add some prints and watch your console log.  Perhaps you’re adding some runtime listeners over and over.  Print out your memory usage and see what memory foot print you’re using.  Its very possible that you might not have a leak, but that you’re using a lot of memory anyway.

Rob

Hi Rob;

Thanks for the reply. I figured without looking at the code it would be hard for anyone to help. I have checked the runtime listeners and for each instance of adding one I remove it when the function is done / animation is complete, etc.

The app is using about 3.5 MB LUA memory and 45MB Texture memory on the iPad retina in corona simulator according to the performance meter I found on this forum - sorry I don’t have the link any more.

The memory is constantly increasing and then after about 20 seconds or so it goes back down to the level it started at. I don’t know if that is normal memory behaviour or not - however when I run just the performance meter in an “empty” app it does the same thing only the climbing is slower.

Anyway, that’s actually an answer for me - I was wondering if perhaps it simply uses too much memory or maybe there is just way too much going on when I hit spin or when it’s finished spinning with all of the win animations and sounds etc…

How do  I do this? “Print out your memory usage and see what memory foot print you’re using.” Is there a way to see what is actually using how much memory while the app is running? That would be awesome if I could see that - for instance - how much memory the listeners are using, or the images etc. and how it changes as I do things in the app. LOL maybe a tall order? I don;t know.

Cheers!

Oh yeah one more question for now. Is it better to pre-load audio and then simply play it? or is it better to load play dispose all when you want to play a sound?

The reason I ask is I notice the frame rate drops significantly at the end of the spin cycle on the app when the audio plays then when it is done playing it goes back up a bit, but never back to 30FPS after about 10 spins. LOL Wow confusing.

Cheers!

The storyboard library (though we are deprecating it) has a storyboard.printMemUsage() API Call.  See: 

http://docs.coronalabs.com/api/library/storyboard/printMemUsage.html

It’s basically showing the results of system.getInfo(“textureMemoryUsed”) and collectgarbage(“count”).  Now the collectgarbage() returns memory in Kbytes.  The system.getInfo() returns it in bytes. 

Yes, it is normal for memory to go up and down.  If it goes up by 20 then down by 10 and up by 20 then down by 10 you probably have a leak.

As for the audio question, it’s a balance.  Loaded audio takes up memory.  Larger tracks take up more than smaller tracks.  44khz stereo tracks take up more memory than 11khz mono tracks.  But large tracks take time to load (though we do have audio.loadStream() which helps hide the delay of loading.   I personally would make sure my sound files are as small as I can get them.  Load sounds you will use over and over at the beginning and keep them around. Things only needed for the scene should probably be loaded in the createScene() and disposed in destoryScene().

OK great thanks for the replies. I jus wasn’t sure if it could just be from memory usage (e.g. the system has too much going on perhaps?).

Cheers.

OK so I thought I had the problem solved yesterday, unfortunately not.

I have narrowed the source or cause of the issue to one big (huge?) function in my code, when I comment it out the problem seems to go away. The frame rate does;t drop as drastically ( about 2 or 3 FPS per 60 plays / cycles as opposed to half after 10 plays or cycles as it was before).

So heres a dumb newbie type question for you…

Is it better for performance sake to split this large function into a bunch of smaller functions? Perhaps even make it into a completely separate  module? Would that make a large impact on performance?

I’m hoping that is the case and I am about to embark on this endeavour… I will report back soon.

Any help/comments would be greatly appreciated.

Cheers!

I guess a lot would depend on what you’re doing ni that large function.  If you’re still executing 1000 instructions, it doesn’t really matter how you break it up.  You probably should spend more energy finding out why the function is taking up so much time.

From a purely ability to support your code, long functions are hard to read, hard to trouble shoot and slow to edit (think about how much scrolling up and down you do in your editor).  You will be best to break it down for your own sanity.  Now you might find your performance problem by breaking things down.  You can find problems that way.

Rob

Yes, sanity is crucial. Lol Ok thank you again. I appreciate the info. I will post how I make out. Cheers Rob.