I usually never ask for help on this kind of stuff, it took me 3 days of debate whether to ask or not. I decided to try using Love2D to help myself understand lua a bit better, and while working with it, I somehow made myself a memory leak when making a clone of breakout , there isn't much code and I was relatively sure I set the references to nil, but I can't seem to find it.
Orz
To Produce Leak:
Lose all your lives 2-3 times and gameplay takes a huge toll in performance.
At the restart game function in game state I call self.gObjBrick = self:generateLevel() after removing everything from table :*(
It should be somewhere around there.
Please help
Memory Leak, help, 3rd day and can't find [Solved]
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Memory Leak, help, 3rd day and can't find [Solved]
- Attachments
-
- BreakoutClone.love
- My breakout Clone
- (31.79 KiB) Downloaded 103 times
Last edited by BPLeon on Tue Jan 27, 2015 9:58 pm, edited 1 time in total.
Re: Memory Leak, help, 3rd day and can't find :*(
I havent used any physics engines for love2d so this is more like a guess, but from quick glance you aren't removing the collider from the world.
Another problem/potential problem in future that I noticed in your code is inside the removing from table. You have inside gamestate, oncollide following thing:
Now this doesn't probably do exactly what you are hoping it does in case you have collision with 2 bricks at the same time. It skips objects, because when you remove object from an array with table.remove(), the size of table also gets substracted. Now lets say for example:
Now you would think that this actually removes numbers 3 and 4, but it actually removes values 3 and 5, because the table is being changed while it is being iterated. If you index the table from max to min you can avoid this problem where you actually skip the indexes when removed (this is common problem with linked lists). For example once i hits 3, the table looks like { 1,2,4,5 }, and then 4th index is actually 5.
Edit:
I went outside for a walk and thought about this, and I came to conclusion that you are most likely, without really knowing how hardoncollider works, checking all the collisions against each other collisions. This means that essentially you are doing 99% of unneccessary collision checks, bricks vs brick collision. This leads to n*n amount of collision checks. The way how this is generally solved is by assigning collision groups, and with groups you only check each group against each group. Basically if using something like table logic what I am suspecting you are doing for collision check is something like:
Well that is just my educated guess, someone with better knowledge about hardoncollider can correct me if I am wrong. Also I wouldn't be surprised if this doesn't make things any clearer.
Code: Select all
function BRICK:Destroy()
self.xPos = nil
self.yPos = nil
self.width = nil
self.height = nil
self.bColor = nil
Collider:remove( self.Collider ) -- <-- added this line, it removes the collision from the world at least I think it does
self.Collider = nil
self.drawnBrick = nil
self = nil
end
Code: Select all
for a, brick in ipairs (self.gObjBrick) do
...
brick:Destroy()
self.gObjBrick[a] = nil
table.remove(self.gObjBrick,a)
...
end
Code: Select all
local t = {
1,2,3,4,5
}
for i,v in ipairs( t ) do
if i == 3 or i == 4 then
table.remove(t,i)
print( i, v )
end
end
Edit:
I went outside for a walk and thought about this, and I came to conclusion that you are most likely, without really knowing how hardoncollider works, checking all the collisions against each other collisions. This means that essentially you are doing 99% of unneccessary collision checks, bricks vs brick collision. This leads to n*n amount of collision checks. The way how this is generally solved is by assigning collision groups, and with groups you only check each group against each group. Basically if using something like table logic what I am suspecting you are doing for collision check is something like:
Code: Select all
| Ball | Brick1 | Brick2 | Brick3 | Brick4 | ... | Paddle |
------+------+----------+--------+--------+--------+-----+--------+
Ball | | x | x | x | O | ... | x |
Brick1| x | | x | x | X | ... | x |
Brick2| x | x | | x | X | ... | x |
Brick3| x | x | x | | X | ... | x |
Brick4| x | x | x | x | | ... | x |
...
Paddle| x | x | x | x | X | ... | |
Re: Memory Leak, help, 3rd day and can't find :*(
The problem is with BRICK:Destroy() just like Muris wrote.
Most of your =nil, all of your garbagecollect and table.removes are useless. Especially this beauty:
Most of your =nil, all of your garbagecollect and table.removes are useless. Especially this beauty:
Code: Select all
self=nil
Re: Memory Leak, help, 3rd day and can't find :*(
This line was exactly what I needed, it actually removes the object and the performance stays the same.Code: Select all
function BRICK:Destroy() self.xPos = nil self.yPos = nil self.width = nil self.height = nil self.bColor = nil Collider:remove( self.Collider ) -- <-- added this line, it removes the collision from the world at least I think it does self.Collider = nil self.drawnBrick = nil self = nil end
Are you talking about this part of it?Another problem/potential problem in future that I noticed in your code is inside the removing from table. You have inside gamestate, oncollide following thing:
Now this doesn't probably do exactly what you are hoping it does in case you have collision with 2 bricks at the same time. It skips objects, because when you remove object from an array with table.remove(), the size of table also gets substracted...Code: Select all
for a, brick in ipairs (self.gObjBrick) do ... brick:Destroy() self.gObjBrick[a] = nil table.remove(self.gObjBrick,a) ... end
Code: Select all
ballToBrick = self:Normalize2({NormX,NormY})
angle = math.deg(math.acos(self:Dot(ballToBrick,{0,1})))+tempAngle
brick:Destroy()
self.gObjBrick[a] = nil
table.remove(self.gObjBrick,a)
--self.txtScore = self.txtScore + 10
collectgarbage("collect")
if angle <= 45 or angle >= 315 then
self.gObjBall:goUp()
elseif angle <= 135 and angle >= 45 then
self.gObjBall:goRight()
elseif angle <= 225 and angle >= 135 then
self.gObjBall:goDown()
elseif angle <= 315 and angle >= 225 then
self.gObjBall:goLeft()
end
return
This means that essentially you are doing 99% of unneccessary collision checks, bricks vs brick collision. This leads to n*n amount of collision checks.
I do agree with this statement, I'm not really sure how hardoncollider works with something like this, and the fact that the collider still persist and the fact more getting added on makes the game lag n*n number of times, thus checking every single one and hitting
Code: Select all
local other
if shapea == self.gObjBall.Collider then
other = shapeb
elseif shapeb == self.gObjBall.Collider then
other = shapea
else
return
end
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 7 guests