Page 1 of 1

Game uses 50MBs, still I get PANIC: (not enough memory)

Posted: Thu Jan 24, 2019 1:02 pm
by andras
My game is getting big, I am using three 1500x10000 canvases for the background, and several particle systems.

Since I started doing this, I'm getting random crashes with no output to the console and sometimes crashes with this output:

Code: Select all

Mem (MB)	56.4
Mem (MB)	52.5
PANIC: unprotected error in call to Lua API (not enough memory)
AL lib: (EE) alc_cleanup: 1 device not closed
I am printing the used memory every 3 seconds with the following line:

Code: Select all

print('Mem (MB)', math.ceil(collectgarbage('count')/100)/10)
I am using LOVE 11.1 on MacOS. Other Mac users also complained, no crashes on Windows AFAIK. I also use luasec, that's the only c-lib dependency.

Any tips for pinpointing the issue? Thank you!

Re: Game uses 50MBs, still I get PANIC: (not enough memory)

Posted: Thu Jan 24, 2019 1:48 pm
by grump
10000 might become problematic if you plan to target weaker/older devices.

It may be a memory leak of some kind. Do you create lots of LÖVE objects (anything you create with love.<module>.new*, e. g. love.image.newImageData)? Note that those are not counted by collectgarbage.

Re: Game uses 50MBs, still I get PANIC: (not enough memory)

Posted: Thu Jan 24, 2019 5:47 pm
by andras
Thanks Grump! Good to know that LOVE objects reside outside of the lua heap, therefore not counted.

I really hope that's the answer, although I have more than 100 matches for love.*.new* so it takes a while to check. It looks like I'm not doing
it inside the update/draw loop, but it's hard to trace. Is there a tool for tracing LOVE object allocations?

(I know about the large canvas issue on older graphics drivers, I'll chop up the canvases at a later stage. It still won't affect the number of pixels stored in VRAM, though.)

Re: Game uses 50MBs, still I get PANIC: (not enough memory)

Posted: Thu Jan 24, 2019 6:43 pm
by grump
andras wrote: Thu Jan 24, 2019 5:47 pm I really hope that's the answer, although I have more than 100 matches for love.*.new* so it takes a while to check.
There are more functions that you might want to consider here that don't match that pattern, for instance Canvas:newImageData, or Data:clone.
Is there a tool for tracing LOVE object allocations?
None that I'd know of, but you could shadow those functions to trace them, like this:

Code: Select all

local newImageData = love.image.newImageData

love.image.newImageData = function(...)
    print('newImageData')
    return newImageData(...)
end

Re: Game uses 50MBs, still I get PANIC: (not enough memory)

Posted: Thu Jan 24, 2019 10:14 pm
by andras
Cool trick that, shadowing. I wrote a small module to trace all love functions starting with 'new'. It also prints the function arguments.

Code: Select all

local function trace(moduleName, mod, funcName, func)
  mod[funcName] = function(...)
    print(moduleName..'.'..funcName, ...)
    return func(...)
  end
end

for moduleName, mod in pairs(love) do
  if type(mod) == 'table' then
    for key, func in pairs(mod) do
      if type(func) == 'function' and type(key) == 'string' and key:sub(1, 3) == 'new' then
        trace(moduleName, mod, key, func)
      end
    end
  end
end
I got loads of traces for newImage, newQuads, newParticleSystem and such, but they all happen during initialization, not the game loop. I'll keep my eyes open for the crash and see if something goes haywire just before it happens.

Any ideas why the game crashes with a PANIC, though? LOVE stores data off the lua heap (userdata?). Does this still count against luajit's 2GB limit?

Re: Game uses 50MBs, still I get PANIC: (not enough memory)

Posted: Fri Jan 25, 2019 2:59 am
by monkyyy
>I am using three 1500x10000 canvases for the background

Shouldn't you be using some sort of loading system at that size?

Re: Game uses 50MBs, still I get PANIC: (not enough memory)

Posted: Fri Jan 25, 2019 7:57 pm
by andras
Do you mean like maybe I should only draw what's in the viewport? Quickly render the next canvas when the player starts scrolling off the current one?

Maybe. Sometimes I zoom out and then I kinda need to show almost the whole canvas (scaled down). Maybe I could pre-draw a single big 0.5x resolution canvas (for zooming) and many smaller 1x resolution canvases for normal play on the fly. It would be quite complex so before I implement this I'd like to know that the crashes are due to my large canvases as opposed to something else (eg. spawning lots of LOVE objects in the main loop, which seems not to be the case).

Re: Game uses 50MBs, still I get PANIC: (not enough memory)

Posted: Fri Jan 25, 2019 11:30 pm
by andras
I found the reason why I was retaining way too much memory. Totally my fault. I implemented time-rewind (a'la Braid) 5 years ago and forgot how much memory it takes to store the game state at every frame for the last 10 seconds. A little bit of optimization decreased my memory footprint fourfold, should be fine for now, hope it won't crash anymore.

The only generally useful trick I learned (apart from Grump's allocation tracing tip) was that I should print the memory usage every 0.5 seconds, 3 seconds is just too slow to see patterns.

Thanks Grump and Monkyyy for the suggestions, they helped a great deal!