Corona® Profiler- A Line-by-Line Analysis of Your Code - New Update

@M.Y. Developers,
Thanks.

I’ll give that a try.
Jeff

[import]uid: 14119 topic_id: 17975 reply_id: 82353[/import]

Just a quick note about mode 4. Even so I am still trying to understand the report I am getting, the new version already detected a bunch of global variables and even functions that had no business being global! I simply stupidly forgot to put the word local in front of them. I can see why some of my recent leaks are partially due to globals that are never cleaned up between scenes. I had very little time to investigate further today but I am convinced this new mode will help tremendously. I just need to get my head around the result window I am getting. By the way what will be the best to post my results window in this forum. I tried to copy and paste but i cannot seems to select all and copy.

Thanks guys again for a tremendous tool!

Mo

Ps: I end up put a diff line at the top of my menuScreen.lua since I wanted to see the difference every time I come back from my gameScreen.lua where I suspect the leak is… [import]uid: 49236 topic_id: 17975 reply_id: 82423[/import]

Mo,
Good to hear you are finding and fixing problems with Profiler! The results window can be a little confusing but will provide you with a plethora of useful information. Let us take the example here and think about what the results should be.

profiler = require("Profiler")  
profiler.startProfiler{mode=4}  
local memoryLeak = {}  
local noLeak = {}  
profiler.diffSnapshot() --first call will not show anything just records the state.  
local function createStuff()  
 memoryLeak[#memoryLeak+1] = display.newCircle(math.random()\*100, math.random()\*100, 20)  
 memoryLeak[#memoryLeak]:removeSelf() --small leak here, we forget to nill  
 noLeak[#noLeak+1] = display.newCircle(math.random()\*100, math.random()\*100, 20)  
 noLeak[#noLeak]:removeSelf()  
 noLeak[#noLeak] = nil --no leak here, we nil  
 profiler.diffSnapshot() --will catch the memory leak in memoryLeak local variable  
end  
Runtime:addEventListener("enterFrame", createStuff)  

you will see a repeating table that looks like this
-------------------------diff snapshot “2”-----------------------
size var name defined in
increase
1 memoryLeak main.lua (main chunk)

And indeed, every frame memoryLeak table increases by 1. Notice how noLeak does not even show up, this is because it does not increase in size from diffSnapshot calls.

Hope that clears things up,
M.Y. Developers [import]uid: 55057 topic_id: 17975 reply_id: 82817[/import]

Yes the example helps. By the way is the memory increase of 1 means 1K? I also sent you an example of my report by email. I hope you can make sense of it.

Thanks again.

Mo [import]uid: 49236 topic_id: 17975 reply_id: 82871[/import]

Hello,

I think I “may” have found my 2K memory leak. But do not yet pin point the actual object(s). Every time I switch between my main screen and my game screen I can see the following line in the profiler:

2 - #display object - global

Which I interpret as a 2K lua memory for an image left behind. Anyway to drill more on what display object it is referring too? Is the 2 really means 2K in the report?

Thank you again for a great tool which helped me so much in cleaning my code. And my code needed a lot of cleaning!

Mo [import]uid: 49236 topic_id: 17975 reply_id: 83164[/import]

Hello Mo,
you can modify the code above to cause a 1 #global object leak. You can do this with the following:

profiler = require("Profiler")  
profiler.startProfiler{mode=4}  
local memoryLeak = {}  
local noLeak = {}  
profiler.diffSnapshot() --first call will not show anything just records the state.  
local function createStuff()  
 memoryLeak[#memoryLeak+1] = display.newCircle(math.random()\*100, math.random()\*100, 20)  
 memoryLeak[#memoryLeak]:removeSelf() --small leak here, we forget to nill  
 noLeak[#noLeak+1] = display.newCircle(math.random()\*100, math.random()\*100, 20)  
 --noLeak[#noLeak]:removeSelf() We forgot to remove it!  
 noLeak[#noLeak] = nil --no leak here, we nil  
 profiler.diffSnapshot() --will catch the memory leak in memoryLeak local variable  
end  
Runtime:addEventListener("enterFrame", createStuff)  

now noLeak will still not have a memory leak but we will have extra 1 #display objects increase per frame. The numbers shown by profiler are not kilobytes, sorry for the confusion. Rather these are the increase in the number of objects in the table itself. Unfortunately it is not trivial to get the memory size of a table in Lua. However, memory leaks occur when we forget to nil something so we end up having an increase in the number of elements.

-M.Y. Developers [import]uid: 55057 topic_id: 17975 reply_id: 83178[/import]

Thanks! Ok, so I may have some display objects that I am not removing. They also should not be global. My game screen lua is where all my elements are set so there is a lot of display objects.

Thanks for the info. It is good to know that the 2 was not the size of the table.

Even so I am still struggling to find my new memory leak, it will have been almost impossible to figure out it came from a global display not being removed without your great tool.

Mo [import]uid: 49236 topic_id: 17975 reply_id: 83200[/import]

Mo,

Hope things are going well. Were you able to find the problem with your code?

Thanks for your support,
-M.Y. Developers [import]uid: 55057 topic_id: 17975 reply_id: 83923[/import]

Hello,

Thank you for checking. I am working on it as we speak! It seems that I have a problem when I switch between gameScreen to menuScreen. While I am in main game module (gameScreen) the profiler mode shows that the memory use stabilize nicely so I will think I do not have a memory leak while playing. But when I switch back to main menu, I can see my memory useage increase slowing by around 2K. Using mode 4 I found bunch of globals that were not suppose to be globals (as I said before) but now I am hunting for the memory leak that I am sure is there.

I put a profiler.diffSnapshot() at the start of the main menu module so I can see what is happening when the game is over and comes back to the main menu. A lot of time there is nothing in the snapshots but sometimes I can see some variables or functions adding some but they seems to be removed on subsequent snapshots.

Because I do not think it is a huge leak (2 k, but still would cause problem eventually) and it happens when exiting a module, it is hard to tell where it is located. I will also try to come back to the mode 3 and see what happened when switch back and forth.

For the next version, I would really suggest to change the coloring of the graph (from green-blue to say green-red) to make it easier to see the changes. Also a way to flag a specific function on the graph will be very cool too!
I will keep you posted here of what I found.

Thanks again for the great support.

Mo

ps: maybe a quick question: I can see that some variables get added in one snapshot then get deleted in the next snapshot. That seems strange to me since the profiler.diffSnapshot() line is in the first line of the main menu. I would think that every snapshot would not have a variable added in one snapshot and then removed on the next. I will think that my code should not keep memory of a variable past the clean() function (director) on the gameScreen IF I was doing a good job at cleaning up after myself. Like I said a lot of snapshot are empty when switching back and forth but sometimes I get these variables that are added and then removed. Maybe it is normal and I am just imagining things:) [import]uid: 49236 topic_id: 17975 reply_id: 83928[/import]

Hello Mo,
Thank you for your suggestions we are trying to figure out a good way to flag a particular function for profiling. It is difficult because functions have scopes just like tables and you may get namespace collisions. Indeed the color problem will be addressed for the next version.

Now for your question. When a variable is defined for the first time it will show up in the diffSnapshot() function. So the next time you call diffSnapshot it will show that those variables have increased (after all they have increased from 0 to some value.) However, the important thing you should look for are variables that increased consistently between snapshots. You can do a fullSnapshot occasionally to get an absolute size of all your variables.

Hope that helps,
M.Y. Developers [import]uid: 55057 topic_id: 17975 reply_id: 84299[/import]

Hey thanks for the info.

I think I found my big leak. It seems to have been a transistions I forgot to cancel (it was a transistions embedded into another…). Also using mode 4 it was looking I had a variable that global which should not have been (another one!) thanks the profiler I found the exact variable!

I have to admit looking for memory is very frustrating. Time could be better spent actually doing dev but of course memory leaks squashing is part of the job…

In any event thanks for your tools that job is made easier. Still it is a lot work. One of the issue is the shear of data with all the profiling modes. I usually switch between modes and also use other memory leak profiler like displaying memory use or the graphic display if memory and fps found in the forum.

Maybe what is missing is a good methodology to use the profiler in doing memory leak check. In any event your profilers are one of the most useful tools I ever bought in my Corona dev ( that list include Particile Candy and CPM editor)

Thanks again for the support.

Mo.

Ps1: Doing a long profile, I have notice that memory size step up a little a long time after the start of the game ( so not just assets starting) but then after a while it stabilize from that point on. That could look like a leak if not doing a long enough profile. Is that your understanding of what should happen?

[import]uid: 49236 topic_id: 17975 reply_id: 84304[/import]

Hi Mo,

When you fixed your transitions problem did the 2 #displayObject go away as well? This is important to note. It may be the case transitions are represented as display objects?

Yes we agree there is a lot of data being displayed on the graphs and we hoped mode 4 will help pinpoint things better. As for methodology, the best way to find leaks would probably be to use the timeline (mode 3) to see if there are leaks and give you a general idea which files/functions they may be in. Then use mode 4 to drill down the exact variable names that may be contributing to the leak using the same method you are using now.


Ps1: Doing a long profile, I have notice that memory size step up a little a long time after the start of the game ( so not just assets starting) but then after a while it stabilize from that point on. That could look like a leak if not doing a long enough profile. Is that your understanding of what should happen?


Could be anything but it is possibly due to adding more display objects up to a maximum for your program. Display objects must be stored somewhere in memory and Lua grows arrays by 2^n increments. So as you add more display objects the table grows up to a certain amount. Even if the table shrinks again Lua doesn’t seem to reduce the size of the table immediately because allocating memory may be very expensive. After all if the table was large before, it might be large again soon. It is ok if things stabilize, you just want to be careful if you see a linear increase in memory.

Thanks,
M.Y. Developers [import]uid: 55057 topic_id: 17975 reply_id: 84402[/import]

Hello,

@M.Y:

Thank you so much for getting back to me and for the great info. Actually the way i found out about the missing timer cancelation was when I got something like this in the mode 4 report (diff was set in the top of the main menu lua and switched back and forth with game screen)

+/- 6 : e : function function2/1(e) in gameScreen2.lua

The functions 1 and 2 are declared like below and basically are used to make a laser beam blink rapidly. I am pretty sure there is a much better way of doing this.

[lua]local function1, function2
local trans

–local rect = display.newRect(10,10,300,40)
– rect:setFillColor(255,255,255)

function function1(e)
trans = transition.to(laser,{time=20,alpha=1, onComplete=function2})
end

function function2(e)
trans = transition.to(laser,{time=20,alpha=0, onComplete=function1})
end

local laserTransition = transition.to(laser,{time=200,alpha=0, onComplete = function1})[/lua]

So when I looked at the problem function, I saw that that I was canceling laserTransition but but not trans. Once I did, I could see that my +2K was gone.

In term of #display, I found something and dealt with but for the life of me I do not recall what it was but I am sure it was a real display that I forgot to remove at the gameScreen exit. Actually I am getting another #display (global) so i must have introduced something else I guess.

I am curious about mode 3. I usually use it just to tell me if memory is stabilizing over time or increase without end (by looking at the general shape of the curve of course…plateau at the end). There are other tool like the great graphical memory/fps profiler loq_profiler.lua that give the “same” result. But yours is obviously more advance since it is gives the line line add/removal of memory. I have just hard time using it that way since it is hard to tell if an increase is normal or abnormal. It is also hard to follow a specific function/lines that increase memory and then decrease memory because of the great amount of data involved.

I am not sure how hard it will be but do you think it is possible to have 2 mode 3’s? one at the line by line like now and one that only shows changes at the function level? That way we could start with a function level profile and then we find the “bad” functions we could turn on the line-by-line mode. Again please take this with a grain of salt since I have no idea how difficult is it to do and I do not want to mislead you about this.

I guess, I am trying to figure out how to best use mode 3 to find functions that increases memory with never releasing that memory. But I agree with you that mode 4 is complementary to mode 3 and it is a GREAT addition!

Thanks M.Y

Mo.

[import]uid: 49236 topic_id: 17975 reply_id: 84491[/import]

Mo,

Thanks for letting us know of your experiences! It will be sure to help everyone here in the forums. We agree that mode 3 generates a lot of information and the only thing you can get from it is a yes or no answer. It is very difficult to narrow down a leak this way because memory is not freed on the same line it was defined.

I am not sure how hard it will be but do you think it is possible to have 2 mode 3’s? one at the line by line like now and one that only shows changes at the function level? That way we could start with a function level profile and then we find the “bad” functions we could turn on the line-by-line mode.

Yes this is a good idea! We will look into it. Be careful though, just because you allocate a lot of memory in a particular line does not necessarily mean it is the source of the leak.

Thanks,
M.Y. Developers [import]uid: 55057 topic_id: 17975 reply_id: 84742[/import]

Hi M.Y.developers,

my game is base on director class.

Where do i have to do the initialization of profiler?

If i put it in the beginning of main.lua, i get the message:

profiler stopped, change in memory is: 299.095703125 KB (large positive numbers may indicate a memory leak
Corona Simulator(804,0x2bd82c0) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can’t allocate region
*** set a breakpoint in malloc_error_break to debug

regards

Thomas [import]uid: 52314 topic_id: 17975 reply_id: 85180[/import]

Hello Thomas,

That is very strange it seems like it is running out of memory. Can you send us your project files so we can replicate the problem here and fix it. Have you perhaps accidentally redefined the debug global variable?
our email address is mydevelopersgames@gmail.com
Thanks,
M.Y. Developers [import]uid: 55057 topic_id: 17975 reply_id: 85336[/import]

Hi MY Developers,

I want to purchase this profiler. but when I was reading this post, at post#48 you mentioned it is not possible to profile on device.
I have problem where my game crashes on device occasionally and never crashes on simulator.
your tool will be able to help me solve this problem?

[import]uid: 97420 topic_id: 17975 reply_id: 86057[/import]

Hello y.sravankumar,

Thank you for considering our product!
Crashes can happen due to many causes. One of the most common however are memory leaks. Since your computer (hence the simulator) has so much more memory than the device, memory leaks can probably tolerated for a longer time until it crashes. Profiler can defiantly help you find memory leaks if they are present, resolving these may resolve the crashing problem. If you are not satisfied with Profiler just email us and we will give you a refund.

Thanks,
M.Y. Developers [import]uid: 55057 topic_id: 17975 reply_id: 86072[/import]

I have purchased profiler. I’ll run my code with profiler. hope it’ll help me fix the issue [import]uid: 97420 topic_id: 17975 reply_id: 86079[/import]

@M.Y.
Profiler did not help my cause. but I’ll keep it, I see it as a useful tool to have.

cause of my problem is physics.stop() function call(but I have to stop physics).
I’m trying to come up with sample code to report bug

[import]uid: 97420 topic_id: 17975 reply_id: 86100[/import]