sjmuse: I know that feel :lol:
khanh.dq: This is what I found before. Group does not have problem, but snapshot has.
Anyway, thanks for your help, khanh.dq and davebollinger
Rob: Thanks. By the way, can I use “collectGarbage” instead of waiting?
sjmuse: I know that feel :lol:
khanh.dq: This is what I found before. Group does not have problem, but snapshot has.
Anyway, thanks for your help, khanh.dq and davebollinger
Rob: Thanks. By the way, can I use “collectGarbage” instead of waiting?
I think the answer is No. The problem is display.newSnapshot function, not Lua leak. And collectGarbage only works with Lua. And more, collectGarbage auto be called by Lua. You just need to do it manually in some special case: maybe when you remove a thousand objects and need to create another thousand immediately, so you can call collectGarbage before do that. Otherwise, you really don’t need to work with collectGarbage.
You can still use snapshot and wait for new Corona DailyBuild fixed it before releasing your game
Btw, when you have a problem and need to report, keep your code’s as simple as possible. Like that, you don’t need to use table and create too much snapshots, so everyone may think that the memory problem is somewhere with those tables . Just focus on snapshot
Thanks for your advice.
As Rob said, the “collectGarbage” has an interval. I just want to know if I can skip such interval when testing.
Also, as Rob somehow implies, I would not advise to hunt for memory leaks and instead, while developing, just place a memory usage counter on top of everything that monitors constantly, and only tackle issues when a very specific problem arises.
The same for releasing texture memory, by the way: in my latest game, instead of cleaning up every imageSheet after use (and then needing to reload it again later on) I find it’s easier to just keep them in memory.
You can call the garbage collector whenever you want. Just be aware that it will be a big performance hit on your app. But if there is a leak (yours or ours), this won’t fix it.
Rob
just to further clarify: as of Lua 5.1 (which is what Corona currently uses) overall garbage collection performance is proportional to memory usage (specifically, the number of reference-counted objects, rather than their total size), and the gc is constantly running incrementally, so unless you’re currently using lots of discrete memory instances, and/or have recently done a lot of thrashing, the performance hit of calling for a full collect might/not be significant.
[also note that if you have need to call the gc repeatedly, you can explicitly stop the internal incrementals, and step it yourself with size and frequency of your own choosing. (advanced topic, and not for the faint of heart, but a potential performance gain in some very specific instances - just be sure to restart it later when done stepping it yourself!)]
Sorry to use the old post, But the problem seems still exist.
I use the following code to test:
for i = 1, 1000 do local snapshot = display.newSnapshot(100, 100) display.remove(snapshot) snapshot = nil end
And the result:
Dec 24 18:33:56.994: memUsage = 821.044 KB
Dec 24 18:33:56.995: texMemUsage = 10.004 MB
Dec 24 18:33:58.002: memUsage = 774.126 KB
Dec 24 18:33:58.002: texMemUsage = 10.004 MB
Dec 24 18:33:59.003: memUsage = 1260.154 KB
Dec 24 18:33:59.003: texMemUsage = 10.004 MB
Dec 24 18:34:00.019: memUsage = 1213.279 KB
Dec 24 18:34:00.019: texMemUsage = 10.004 MB
Dec 24 18:34:01.027: memUsage = 1213.279 KB
Dec 24 18:34:01.027: texMemUsage = 10.004 MB
Dec 24 18:34:02.035: memUsage = 1213.279 KB
Dec 24 18:34:02.035: texMemUsage = 10.004 MB
Dec 24 18:34:03.042: memUsage = 1213.279 KB
Dec 24 18:34:03.042: texMemUsage = 10.004 MB
Dec 24 18:34:04.051: memUsage = 1213.279 KB
Dec 24 18:34:04.051: texMemUsage = 10.004 MB
Dec 24 18:34:05.060: memUsage = 1635.154 KB
Dec 24 18:34:05.061: texMemUsage = 10.004 MB
Dec 24 18:34:06.068: memUsage = 1588.279 KB
Dec 24 18:34:06.068: texMemUsage = 10.004 MB
Dec 24 18:34:07.077: memUsage = 2138.154 KB
Dec 24 18:34:07.077: texMemUsage = 10.004 MB
Dec 24 18:34:08.084: memUsage = 2091.279 KB
Dec 24 18:34:08.084: texMemUsage = 10.004 MB
Dec 24 18:34:09.092: memUsage = 2091.279 KB
Dec 24 18:34:09.092: texMemUsage = 10.004 MB
The memory usage is increase every time when I run the above “for” loop. although it will release some memory after 1-2 second.
If I replace the “newSnapshot” to “newGroup”, no memory leak occur.
You cannot do these kinds of tests to “prove” a leak. This simply isn’t how Lua’s garbage collection works. Garbage collection runs in intervals and it’s not a fixed amount of time, there are many factors that trigger when Lua cleans up memory. These type of “print memory usage” things only works over a long period of time and can’t be used to measure if one API call is leaking memory.
Rob
Thanks for your reply in Christmas. And sorry for the wordings that I descript the issue
Is there any way to confirm that the memory will release?
For this, I have been tested with “collectgarbage” after the for loop, though it may not be the correct method. No memory release after collectgarbage.
And I tested with display group with object on it. The memory seems will release after 1-2 second.
By the way, one more suspected case is the nested object:
Scroll view -> display group -> scroll view
local baseScrollView = widget.newScrollView(viewOption)
local group = display.newGroup()
baseScrollView:insert(group)
local childScrollView = widget.newScrollView(viewOption2)
group:insert(childScrollView)
Sorry for just a part of code since I’m using mobile to reply.
If I just remove the base scroll view, the memory seems will not release. But if I remove the display group first, all created memory will be cleared.
Just want to make sure if the objects works normally before release the app.
Thanks and Merry Christmas
When I built my first Corona SDK based app, I lost a lot of sleep and stressed out over memory leaks. I didn’t want my first app rejected and I did a lot of what you’re doing. It takes time to learn what causes leaks and how to avoid them.
You also have to have faith that Lua and Objective-C/Java are going to do the right thing for you. One of the nice things about using a high level language like Lua vs. a lower level language like C is that you don’t have to manage your memory. As long as you remove things when your done and nil them, the system will take care of them.
So many people do a tight loop test to try and prove a leak in Corona code and in 100% of the cases, the test isn’t taking Lua’s garbage collection schedule in to consideration. It’s also an unrealistic way people use the code. No one is going to make 1000 snapshots in a fraction of a second.
What you should be worried about is the long term memory usage. If you are not creating new things or you think you are disposing of everything properly, is your memory growing over time.
Rob
Before reply your message, I want to tell you more about what I’m doing:
I’m writing an post-base app, which will have lots of post display in scrollview. In order to understand the performance, I make a test with lots of post, let’s say, 1000 post, in the scrollview. After that, I need to know if I can remove all I created, so I run the remove objects and see if the memory usage is correct. But it failed. So I minimize the factors and find out that the problem may come from here. That’s why I post a question.
Sorry that my following reply maybe a little bit harsh.
For the second paragraph. I have faith that lua will help me to manage the memory correctly, so what I did first is to find out if I did anything wrong. But even I minimized the case, the problem is still here. So I asked here to see if I can have more evidence to prove that I can have “faith” on the system. A programmer should have a responsibility to find out if somewhere may have critical issue, but not in faith. For a user of Corona, it is also a responsibility to tell the developer of Corona that the potential problem may have. As a programmer, we cannot use “faith” as an only attitude.
Besides, I cannot make sure I can remove all I created if I don’t know which memory is created by me.
For the third paragraph. I’m not sure if I have enough consideration on garbage collection. I tried use function “collectGarbage”, but no use. I tried to waited for 5 minutes to see if the memory will release, but no use. That’s why I asked here to see if still anything I can do. By the way, I cannot find any relationship between the memory leak and the so-called “UNREALISTIC WAY TO USE THE CODE”. My intention is to test the performance if lots of objects on the screen. If too much objects is created in the same time will cause problem, I can try to create each object in every second, or even every minute. I just want to make sure if my application will works without critical issue.
Again sorry for my harsh comment. Hope you will understand why I reply in this way. And thanks for your sharing in the first paragraph and the useful advice in the fourth paragraph
Please advice about the test.
For 7 days running of the following code:
local function garbagePrinting()collectgarbage("collect") local memUsage\_str = string.format( "memUsage = %.3f KB", collectgarbage( "count" ) ) print( memUsage\_str ) local texMemUsage\_str = system.getInfo( "textureMemoryUsed" ) texMemUsage\_str = texMemUsage\_str/1000 texMemUsage\_str = string.format( "texMemUsage = %.3f MB", texMemUsage\_str ) print( texMemUsage\_str ) end -- Runtime:addEventListener( "enterFrame", garbagePrinting ) local testSnapShot = {} local function createNewSnapshot() for i = 1, 10 do display.remove(testSnapShot[i]) testSnapShot[i] = display.newSnapshot(100, 100) local img = display.newImageRect("Image/img1.jpg", 200, 200) testSnapShot[i].group:insert(img) testSnapShot[i]:invalidate() end end createNewSnapshot() timer.performWithDelay(1000, createNewSnapshot, 0) timer.performWithDelay(1000, garbagePrinting, 0)
gives the following result:
Jan 6 12:37:17.237: memUsage = 990749.360 KB
Jan 6 12:37:17.238: texMemUsage = 3040.000 MB
Jan 6 12:37:18.484: memUsage = 990762.485 KB
Jan 6 12:37:18.484: texMemUsage = 3040.000 MB
Jan 6 12:37:19.732: memUsage = 990760.610 KB
Jan 6 12:37:19.733: texMemUsage = 3040.000 MB
Jan 6 12:37:20.967: memUsage = 990773.735 KB
Jan 6 12:37:20.967: texMemUsage = 3040.000 MB
Jan 6 12:37:22.220: memUsage = 990771.860 KB
Jan 6 12:37:22.220: texMemUsage = 3040.000 MB
Jan 6 12:37:23.477: memUsage = 990784.985 KB
Jan 6 12:37:23.477: texMemUsage = 3040.000 MB
Jan 6 12:37:24.714: memUsage = 990783.110 KB
Jan 6 12:37:24.714: texMemUsage = 3040.000 MB
Jan 6 12:37:25.955: memUsage = 990796.235 KB
Jan 6 12:37:25.955: texMemUsage = 3040.000 MB
Jan 6 12:37:27.182: memUsage = 990794.360 KB
Jan 6 12:37:27.182: texMemUsage = 3040.000 MB
Jan 6 12:37:28.426: memUsage = 990807.485 KB
Jan 6 12:37:28.426: texMemUsage = 3040.000 MB
Jan 6 12:37:29.682: memUsage = 990805.610 KB
Jan 6 12:37:29.682: texMemUsage = 3040.000 MB
Jan 6 12:37:30.921: memUsage = 990819.025 KB
Jan 6 12:37:30.922: texMemUsage = 3040.000 MB
Jan 6 12:37:32.161: memUsage = 990816.860 KB
Jan 6 12:37:32.161: texMemUsage = 3040.000 MB
Jan 6 12:37:33.398: memUsage = 990829.985 KB
Jan 6 12:37:33.398: texMemUsage = 3040.000 MB
Jan 6 12:37:34.639: memUsage = 990828.110 KB
Jan 6 12:37:34.639: texMemUsage = 3040.000 MB
Jan 6 12:37:35.906: memUsage = 990841.235 KB
Jan 6 12:37:35.907: texMemUsage = 3040.000 MB
Jan 6 12:37:37.152: memUsage = 990839.360 KB
Jan 6 12:37:37.153: texMemUsage = 3040.000 MB
Jan 6 12:37:38.395: memUsage = 990852.485 KB
Jan 6 12:37:38.396: texMemUsage = 3040.000 MB
Jan 6 12:37:39.652: memUsage = 990850.610 KB
Jan 6 12:37:39.652: texMemUsage = 3040.000 MB
Jan 6 12:37:40.891: memUsage = 990863.735 KB
Jan 6 12:37:40.892: texMemUsage = 3040.000 MB
I gave up. :ph34r:
Anyway, we will not use the feature.
He is looking at us as newbie worker, I trust Lua garbage collect more than his words.
I tried his code and really think that Corona has problem with display.newSnapshot
I simplified his code like that:
local function garbagePrinting() collectgarbage("collect") local memUsage\_str = string.format( "memUsage = %.3f KB", collectgarbage( "count" ) ) print( memUsage\_str ) end timer.performWithDelay(2000,function() print("before create ------------------------") garbagePrinting() local a = display.newSnapshot(200,200) print("after create ---") garbagePrinting() timer.performWithDelay(1000,function() print("before remove ---") garbagePrinting() a:removeSelf() a = nil print("after remove ---") garbagePrinting() timer.performWithDelay(500,function() print("long after remove ---") garbagePrinting() print (" +++ ") end) end) end,0)
and here is the result:
You can see memory slowly increase. You just need to modify line 11 from:
local a = display.newSnapshot(200,200)
to
local a = display.newGroup()
and see no memory increase.
If it’s not a Lua leak, so what is difference between display.newSnapshot and display.newGroup ? Did I remove snapshot in the right way with removeSelf function?
local oneSecond = 1000 local tenSeconds = 10000 local function oncePerSecondMemoryCleanupAndReporting() -- -- perform two full garbage collection cycles -- collectgarbage("collect") collectgarbage("collect") -- -- report memory usage -- local mem = collectgarbage("count") print("Lua memory use: " .. mem .. "K") end timer.performWithDelay( oneSecond, oncePerSecondMemoryCleanupAndReporting, 0 ) local theSnapshot = nil local function oncePerTenSecondsCreateOrRemoveSnapshot() -- -- alternately create OR destroy the snapshot -- if (theSnapshot == nil) then theSnapshot = display.newSnapshot(100, 100) print("-- SNAPSHOT CREATED --") else display.remove(theSnapshot) theSnapshot = nil print("-- SNAPSHOT REMOVED -- ") end end timer.performWithDelay( tenSeconds, oncePerTenSecondsCreateOrRemoveSnapshot, 0 ) -- -- report a rough initial memory usage (to define those fns, create the timers, etc) -- collectgarbage("collect") collectgarbage("collect") local mem = collectgarbage("count") print("Initial/Baseline Lua memory use: " .. mem .. "K") -------------------------------------------------------------------------------- -- -- RUN FOR AT LEAST 100 FULL CREATE/REMOVE CYCLES -- -- what you'd like to see: -- all reports following removal stabilize toward some non-increasing value -- -- what you're likely to see: -- creating the snapshot consumes about .4K -- removing the snapshot releases about .2K -- thus gradual leak of about .2K per create/remove cycle
The bug report for this is: Case 38123
Rob
Thanks, Rob
sjmuse: I know that feel :lol:
khanh.dq: This is what I found before. Group does not have problem, but snapshot has.
Anyway, thanks for your help, khanh.dq and davebollinger
Rob: Thanks. By the way, can I use “collectGarbage” instead of waiting?
I think the answer is No. The problem is display.newSnapshot function, not Lua leak. And collectGarbage only works with Lua. And more, collectGarbage auto be called by Lua. You just need to do it manually in some special case: maybe when you remove a thousand objects and need to create another thousand immediately, so you can call collectGarbage before do that. Otherwise, you really don’t need to work with collectGarbage.
You can still use snapshot and wait for new Corona DailyBuild fixed it before releasing your game
Btw, when you have a problem and need to report, keep your code’s as simple as possible. Like that, you don’t need to use table and create too much snapshots, so everyone may think that the memory problem is somewhere with those tables . Just focus on snapshot
Thanks for your advice.
As Rob said, the “collectGarbage” has an interval. I just want to know if I can skip such interval when testing.