At this point I actually pinpointed the problem and that it comes from class.lua. Now I don't really want someone to fix my class anymore but rather to see what I did wrong in the object pooling side so I don't make the mistake again and I can move on using one of the other pooling libs recommended. So if anyone can see the problem (just find it,not fix it). that'd be great. (p.s. you can use the 2 pieces of code to run a program where it creates and destroys puffs).
Love2d stops running after awhile
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: Love2d stops running after awhile
Re: Love2d stops running after awhile
I've tried to do just that, and I gave up. If you can provide one, please do.Gunroar:Cannon() wrote: ↑Wed Dec 30, 2020 5:00 pmSo if anyone can see the problem (just find it,not fix it). that'd be great. (p.s. you can use the 2 pieces of code to run a program where it creates and destroys puffs).
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: Love2d stops running after awhile
If you're talking about the simulation then I'll be with one in a jiffy...(jiffy translates to 2 or 3 days, just kidding...or am I ?) but for real I'm coming with one soonish...
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: Love2d stops running after awhile
Thnx for waiting and bearing with me, here's the code, just put the other two in the same directory...
main.lua
(edited)
main.lua
(edited)
Code: Select all
--edited
null = function() return 5 end
resizeImage = null
inspect = null
log = null
lume = {
uuid=null,
randomchoice = function(t)
return t[math.random(#t)]
end,
wordwrap=null
}
local kwargs = {
uuid = 4,
map = {storeBullet=null,kill=null},
getSource = null
}
game = kwargs
progress = 0
getUpdateCount = null--not needed
class = require "class"
local Puff = require "puff"
local totalPuffs, currentPuffs = 0,0
local function spawnPuff()
local p = Puff:new(kwargs)
p.source = nil
totalPuffs = totalPuffs+1
table.insert(puffs, p)
return p
end
function mass()
for i = 1,1000 do
spawnPuff()
end
end
local function destroyPuff()
local d = puffs[#puffs]
if d then
d:destroy()
puffs[#puffs] = nil
end
end
function copy(t)
local tt = {}
for x, i in ipairs(t) do
tt[x] = i
end
return tt
end
function love.load()
puffs = {}
count = 50
end
function love.draw()
love.graphics.print("Total puffs spawned: "..totalPuffs,10,100,0,2,2)
love.graphics.print("Current puffs made: "..currentPuffs,10,150,0,2,2)
love.graphics.print("Garbage in mb: "..collectgarbage("count")/1024,10,200,0,2,2)
love.graphics.print("texture memory: "..love.graphics.getStats().texturememory/(1024*1024),10,250,0,2,2)
love.graphics.print("frame rate: "..love.timer.getFPS(),10,300,0,2,2)
end
function love.update(dt)
--ppuffs = copy(puffs)
local del = {}
for i = 1,#puffs do
puffs[i]:update(dt,1)
if puffs[i].dead then
del[i] = true
end
end
for i in pairs(del) do
--if puffs[i].dead then
table.remove(puffs,i)
--end
end
count = count+1
if count>3 then
for x=1,100 do
destroyPuff()
end
count = 0
end
currentPuffs = #puffs
end
function love.mousereleased()
--freezes for me at 6000 if object pool size is 5100
--4000 if size is 3000
mass()
end
Last edited by Gunroar:Cannon() on Thu Dec 31, 2020 2:17 pm, edited 2 times in total.
-
- Party member
- Posts: 559
- Joined: Wed Oct 05, 2016 11:53 am
Re: Love2d stops running after awhile
First thing first, you have this piece of code in your puff.lua:
You use this to log stuff that happens in your code, at such a rate that I amassed 15 thousand(!) lines in the resulting log file after running it for a couple of seconds. This is an absurd rate, to put it mildly.
Secondly, in your example code provided, you have the following:
Thus, you are copying the contents of "puffs" to "ppuffs" (a new table, that is global, that is used as a temporary variable) every frame, creating a lot of garbage. Not only that, it's not exactly efficient and wasteful, to the point you don't need the copy() method at all here. You should only have the single "puffs" table, update the puffs contained therein, and remove the contained objects as necessary.
There may be other issues as well (the table.remove in the love.update, for example), but those two were what immediately stuck out to me. No clue as to why the code crashes at 6000 puffs with the pool size 5100, did not delve too deeply into how class.lua's pooling works.
Code: Select all
_LOG_FILE = love.filesystem.newFile("game_log.txt","w")
local function log(_str,file)
local file = file or _LOG_FILE
local str = lume.wordwrap(inspect(_str,1),90)
file:write(str.."\n")
return true
end
Secondly, in your example code provided, you have the following:
Code: Select all
function love.load()
puffs = {}
count = 50
end
function copy(t)
local tt = {}
for x, i in ipairs(t) do
tt[x] = i
end
return tt
end
function love.update(dt)
ppuffs = copy(puffs)
-- ...
end
There may be other issues as well (the table.remove in the love.update, for example), but those two were what immediately stuck out to me. No clue as to why the code crashes at 6000 puffs with the pool size 5100, did not delve too deeply into how class.lua's pooling works.
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: Love2d stops running after awhile
I opened the last of the sites younposted for me .. and here's the basic rundown:
me: wow , so many object pooling libraries
me:*opens link one*
me:*opens link two*
me:
(though I have seen object pool libs and will check them out)
me: wow , so many object pooling libraries
me:*opens link one*
me:*opens link two*
me:
(though I have seen object pool libs and will check them out)
I guess I'm 40% or less ( ) since I didn't just blindly post snippets and followed the advice that MrFariator gave me...
So...yeah, but you've still been helpful and that code I posted should run and have the same problem, so that should help .MrFariator wrote: ↑Wed Dec 23, 2020 6:56 pm ... you can disable most of the game's logic code (by commenting them out in love.update or wherever else), and then step-by-step enable behavior and see when the issues crop up again. That should help you along with narrowing down the issue.
Last edited by Gunroar:Cannon() on Thu Dec 31, 2020 2:24 pm, edited 2 times in total.
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: Love2d stops running after awhile
Oh, MrFariator! Thnx for the replies but I know of the log and don't really use it and only added that copy part for the emulation. Those aren't in the actual use. I might come with a revised version(I think a problem might be from destroy) and the code doesn't crash for you?
Edit: I revised the main.lua to remove copying and it proves it still crashes and it's not from copy. (P.S: it crashes right before one is about to get destroyed)
Edit: I revised the main.lua to remove copying and it proves it still crashes and it's not from copy. (P.S: it crashes right before one is about to get destroyed)
Re: Love2d stops running after awhile
Just to be clear, does the main.lua you've provided still crash on Android? Is there anything that needs to be done to make it crash, or just wait?
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: Love2d stops running after awhile
Just keep tapping(on the screen, that is) until it passes around 6000 or more...because tapping makes more puffs appear. Oh and yes it still crashes.
Re: Love2d stops running after awhile
Thanks for the test case. I've simplified it further, removing puff.lua and Löve from the equation. This test case runs with plain LuaJIT:
The output is:
And then it hangs for a while until it says:
But interrupting while it's hung, gives a hint:
Sometimes in line 10 instead of 9. And this is the part that is running:
Line 10 is the one that adds the id to the notActive table. Printing #notActive there, reveals that it's growing endlessly.
Therefore, yes, you have a leak which manifests itself when you have created and destroyed as many objects as the size of the pool. If you create just one more object, its destruction causes an infinite loop of notActive creation that exhausts the memory.
I haven't tried to follow the logic of your object destruction, therefore I don't know the cause of the infinite loop.
Code: Select all
jit.off()
game = {}
null = function() end
love = {timer = {getTime = null}}
local BaseClass = require"class"
local Derived = BaseClass:extend("Derived", 2)
for i = 1, 3 do
local obj = Derived:new()
print("Destroying " .. i)
obj:destroy()
print("Destroyed")
end
Code: Select all
Destroying 1
Destroyed
Destroying 2
Destroyed
Destroying 3
Code: Select all
luajit: not enough memory
Code: Select all
Destroying 1
Destroyed
Destroying 2
Destroyed
Destroying 3
^Cluajit: ./class.lua:9: interrupted!
stack traceback:
./class.lua:9: in function 'destroy'
main.lua:10: in main chunk
[C]: at 0x555dee0206c0
Code: Select all
local function destroyFunc(self,...)
-- log(name.." pool at "..self.__id.." is being freed.")
local notActive = POOLS[self.__class].notActive
notActive[#notActive+1] = self.__id
return self._destroy(self,...)
end
Therefore, yes, you have a leak which manifests itself when you have created and destroyed as many objects as the size of the pool. If you create just one more object, its destruction causes an infinite loop of notActive creation that exhausts the memory.
I haven't tried to follow the logic of your object destruction, therefore I don't know the cause of the infinite loop.
Who is online
Users browsing this forum: Bing [Bot] and 12 guests