Memory management and graphic objects

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Fenrir
Party member
Posts: 222
Joined: Wed Nov 27, 2013 9:44 am
Contact:

Memory management and graphic objects

Post by Fenrir »

Hi all,

I'm currently having some memory problems on my project, I'm working on loading levels, returning to menus, etc... My current approach is to deference all my level rendering stuff when coming back to the menus hoping it will be garbage collected, and when loading a new level, I'm recreating everything from scratch (approximatively 10 canvas and a little less than an hundred textures using Mesh objects).

But my memory seems to never go down. Even worst, with some stress test and loading/leaving repetitly a level, at some point I get an error "Cannot create canvas: Error in implementation".

Is there something I am missing to destroy a graphic ressource ? Or are they never destroyed, and I'll need to reuse my objects ? It's not a big problem for the canvas, I think I can manage to setup a system to reuse them, but for my textures it's problematic as levels don't share the same textures sets and it can be heavy to keep everything in memory.

Thanks!
Automatik
Citizen
Posts: 57
Joined: Sun Feb 17, 2013 7:05 pm

Re: Memory management and graphic objects

Post by Automatik »

To manually collect garbage, use "collectgarbage()".
User avatar
dusoft
Party member
Posts: 654
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: Memory management and graphic objects

Post by dusoft »

Fenrir wrote:Hi all,

I'm currently having some memory problems on my project, I'm working on loading levels, returning to menus, etc... My current approach is to deference all my level rendering stuff when coming back to the menus hoping it will be garbage collected, and when loading a new level, I'm recreating everything from scratch (approximatively 10 canvas and a little less than an hundred textures using Mesh objects).

But my memory seems to never go down. Even worst, with some stress test and loading/leaving repetitly a level, at some point I get an error "Cannot create canvas: Error in implementation".

Is there something I am missing to destroy a graphic ressource ? Or are they never destroyed, and I'll need to reuse my objects ? It's not a big problem for the canvas, I think I can manage to setup a system to reuse them, but for my textures it's problematic as levels don't share the same textures sets and it can be heavy to keep everything in memory.

Thanks!
love / lua collects garbage when it hits half the size of the memory, usually, so you should be doing manual garbage collection, if you need that.

also, don't use memory-heavy functions such as love.graphic.newImage() etc. in love.graphics.draw() loops, rather create an object before and then just use it. I have created a simple caching handler including garbage collection as a part of my game engine. I can put separate it and post it, if you are interested.
User avatar
Fenrir
Party member
Posts: 222
Joined: Wed Nov 27, 2013 9:44 am
Contact:

Re: Memory management and graphic objects

Post by Fenrir »

Hi guys,

Thanks for your inputs but actually I think that I'm not facing a garbage collection problem, what I want is to be sure that my graphic resources are freed from the RAM bu also from the GPU. And loading everything in the load() is not an option for me as I really have a lot of different data per level and I only want to load them when the level is active.

So the question is if Love is actually supposed to remove all data from an imageor a Canvas from RAM and GPU when it's garbage collected in the LUA side ?

Thanks!
User avatar
Tanner
Party member
Posts: 166
Joined: Tue Apr 10, 2012 1:51 am

Re: Memory management and graphic objects

Post by Tanner »

Fenrir wrote:So the question is if Love is actually supposed to remove all data from an imageor a Canvas from RAM and GPU when it's garbage collected in the LUA side ?
Yes, when an Image gets garbage collected, the C++ destructor for the object gets called which will, in turn, release the data backing it from memory and delete the texture from the GPU.

The relevant code is here: https://bitbucket.org/rude/love/src/765 ... ault#cl-77
User avatar
Fenrir
Party member
Posts: 222
Joined: Wed Nov 27, 2013 9:44 am
Contact:

Re: Memory management and graphic objects

Post by Fenrir »

Thanks for the confirmation.
Actually I found the problem (part of it at least), take this piece of code:

Code: Select all

function love.update(dt)
    local mesh = love.graphics.newMesh( {{0, 0, 0, 0}} )
    local image = love.graphics.newImage("medias/textures/effects/light_mask.png")
    mesh = nil
    image = nil
    collectgarbage()
end
Even if I load my image in each update cycle, memory stays low and stable.
Now take this one:

Code: Select all

function love.update(dt)
    local mesh = love.graphics.newMesh( {{0, 0, 0, 0}} )
    local image = love.graphics.newImage("medias/textures/effects/light_mask.png")
    mesh:setTexture(image)
    image = nil
    mesh = nil
    collectgarbage()
end
Several seconds after launching the application RAM is full and I have an "out of memory" error from Love. It seems the Mesh object doesn't release its texture when it's deferenced.

I found a workaround in my application, before deferencing my Mesh objects, I call:

Code: Select all

mesh:setTexture(nil)
It's a bit tricky, and I still have some memory issues, I think this time it's with shaders, when I send an image uniform to a shader the same problem happens, but I need to do further testing to confirm it.

Anyway, can it be considered as a bug in Love or am I missing something ?

EDIT: OK I just made a few more tests and this code:

Code: Select all

function love.update(dt)
    local shader = love.graphics.newShader(love.filesystem.read("shaders/light.fsh"), love.filesystem.read("shaders/light.vsh"))
    local image = love.graphics.newImage("medias/textures/effects/light_mask.png")

    shader:send("light_mask", image)
    image = nil
    shader = nil
    collectgarbage()
end
It produces the same problem, image is never deferenced and memory grows until an "out of memory" error. It explains the memory leaks I still have in my project, but this time there's no workaround like

Code: Select all

shader:send("light_mask", nil)
as it's not allowed... :/
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Memory management and graphic objects

Post by bartbes »

Indeed there was a memory leak in the meshes, so thanks for finding that. I've not been able to track down a leak in the shader code, though.
User avatar
Fenrir
Party member
Posts: 222
Joined: Wed Nov 27, 2013 9:44 am
Contact:

Re: Memory management and graphic objects

Post by Fenrir »

Thank you very much for the fix.
I'll try to make further investigations for the shaders and let you know.

Cheers,
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Semrush [Bot] and 9 guests