Page 1 of 5

Love2d stops running after awhile

Posted: Thu Dec 17, 2020 7:52 am
by Gunroar:Cannon()
I coded a game for local multiplayer for android devices , so when I had to come to the testing phase I moved the game to my tablet and to another old phone, but when I run the game(with or without connecting) it doesn't last 1 minute before it closes(on the old phone not the tablet). The game runs OK on the tablet and it has an even better frame rate on the old phone(~40fps) but despite that it just closes..
I even added object pools but that didn't work. Can love2d stop because of ram /memory usage or what? Is there a way to check how much ram it uses. What may be the problem??

Re: Love2d stops running after awhile

Posted: Thu Dec 17, 2020 9:14 am
by ReFreezed
Yes, using too much memory will crash the program. Get Lua's memory usage with kbytes=collectgarbage("count"). Note that it doesn't include VRAM usage and some other things. You can get more info with love.graphics.getStats.

Re: Love2d stops running after awhile

Posted: Thu Dec 17, 2020 9:54 am
by Gunroar:Cannon()
Thnx,I'll check if that's the problemo. But can I fix it by calling the garbage collection function manually?

Re: Love2d stops running after awhile

Posted: Thu Dec 17, 2020 11:00 am
by ReFreezed
No, but if you call collectgarbage() right before collectgarbage("count") you'll get a more accurate memory usage number (because no "garbage" has had any time to build up) and it's easier to see exactly how much the memory usage increases over time. If you don't collect garbage manually then Lua does it automatically and you should, in normal cases, see the memory usage going up, then falling down, and be relatively stable over time (and if there's a memory leak it should, of course, go more up than down).

Re: Love2d stops running after awhile

Posted: Thu Dec 17, 2020 10:12 pm
by pgimeno
I've had to call the GC manually when I created many Löve objects. I don't think collectgarbage("count") gives you the RAM used by Löve objects, so the value may be misleading.

Re: Love2d stops running after awhile

Posted: Fri Dec 18, 2020 9:14 pm
by Gunroar:Cannon()
I called the collectgarbage function manually cause it seems I have a memory leak????? But when I keep calling it with "count" multiplayer data doesn't send or barely sends. Does it clean up garbage there maybe?(I use sock.lua).
And also how are memory leaks fixed? Are they caused by when you fail to delete all references to an unused object?

Re: Love2d stops running after awhile

Posted: Sat Dec 19, 2020 3:39 am
by pgimeno
collectgarbage() won't fix memory leaks. collectgarbage("count") only retrieves the amount of used memory, it shouldn't affect program execution. It's weird that something stops working when you add collectgarbage("count"), unless it's something very timing-sensitive.

collectgarbage("count") will only retrieve the amount of memory used by Lua, but not by Löve objects. The size of Löve objects is not visible to Lua, and that's where the problem resides. If Lua does not find enough objects to clean, it won't collect garbage. But if the few existing objects are big, that may fill up the memory quickly.

For example, these two programs report the same memory usage:

Code: Select all

function love.load()
  local x = love.image.newImageData(1,1) -- tiny image
  print(collectgarbage("count"))
  love.event.quit()
end

Code: Select all

function love.load()
  local x = love.image.newImageData(4000,4000) -- huge image
  print(collectgarbage("count"))
  love.event.quit()
end
This program has no leaks, but it will quickly fill up the system memory for the reason mentioned above:

Code: Select all

function love.load()
  for i = 1, 10000 do
    local x = love.image.newImageData(1000,1000)
  end
  love.event.quit()
end
Each iteration, the old object that x was set to in the previous iteration, becomes unreferenced. It's the garbage collector's task to find these unreferenced objects and clean them up; however, from the point of view of the interpreter, 10,000 objects take just around a hundred KB, and it doesn't bother running the GC for that little. It doesn't know that each of these objects actually occupies around 4 MB.

That's just an unfixable bug in the garbage collector, not a memory leak. It's not a memory leak because if you had enough RAM, eventually the GC would run and clear all objects at once, and continue normally as if nothing happened. That's not happening because you don't have enough memory for the GC to do its job in the way it's designed to do it.

This program fixes the issue and does not fill up the system memory:

Code: Select all

function love.load()
  for i = 1, 10000 do
    collectgarbage()
    local x = love.image.newImageData(1000,1000)
  end
  love.event.quit()
end
On each iteration, the garbage collector is forced to run, despite having just one new object every iteration. This keeps the memory usage under control.

A memory leak is a case where your program uses more and more objects without marking any of them for deletion. For example:

Code: Select all

local myObjects = {}
function love.update(dt)
  table.insert(myObjects, love.image.newImageData(1, 1))
end
If nothing in your code clears any element of myObjects, you have a memory leak. Memory will grow and grow, and no call to collectgarbage() will fix it.

Re: Love2d stops running after awhile

Posted: Sat Dec 19, 2020 6:18 am
by ReFreezed
pgimeno wrote: Sat Dec 19, 2020 3:39 am This program fixes the issue and does not fill up the system memory:

Code: Select all

function love.load()
  for i = 1, 10000 do
    collectgarbage()
    local x = love.image.newImageData(1000,1000)
  end
  love.event.quit()
end
Another way is to call release() on the object.

Code: Select all

function love.load()
  for i = 1, 10000 do
    local x = love.image.newImageData(1000,1000)
    x:release()
  end
  love.event.quit()
end

Re: Love2d stops running after awhile

Posted: Sat Dec 19, 2020 11:37 am
by pgimeno
Right, if you know the object that is causing the memory to grow, that's the best solution: first release the object, then either overwrite the variable with another value (e.g. nil) or let it go out of scope. Note that release() does not free the Lua-side object. But after release(), the Lua-side object occupies what Lua expects it to occupy, and Lua's GC works as designed.

Re: Love2d stops running after awhile

Posted: Sat Dec 19, 2020 10:43 pm
by Nixola
Note that the love.lowmemory callback exists and is designed for this kind of issue, if memory is to blame.