Page 1 of 2
[Solved] Memory Leak in only two lines
Posted: Fri May 02, 2014 9:38 pm
by OnlyFails
Introduction:
So I noticed my game was slowly eating up more and more memory and couldn't find out why!
I decided to learn about garbage collection by creating a new, simple love2d project with the following code:
main.lua:
Code: Select all
function love.load()
end
function love.update()
end
function love.draw()
love.graphics.setColor(255, 255, 255, 255)
love.graphics.rectangle("fill", 10, 10, 100, 100)
end
The Problem:
When I run this simple program, the amount of memory displayed in 'Task Manager.exe' slowly increases from around 12 to 4 KB every second until it reaches a peak amount of memory ~22,100 KB to ~22,208 KB
That doesn't seem so bad but when you have 1000's of rectangles being rendered at any given time this adds up, and in my main project I haven't been able to see any peak memory usage as it just keeps rising by a few MB per second.
My Question
Is this normal? Are there any steps I'm missing to preventing memory rising like this?
Thanks in advance!
Re: Memory Leak in only two lines
Posted: Fri May 02, 2014 10:35 pm
by Azhukar
If you have a leak of few mb per second in your code it is not caused by the 2 lines you provided.
Code: Select all
for i=1,10000 do
love.graphics.setColor(255, 255, 255, 255)
love.graphics.rectangle("fill", 10, 10, 100, 100)
end
Some things that can cause higher memory upkeep:
Userdata - creating new userdata every frame. This includes image objects among other things.
Tables - all inaccessible tables are eventually collected, if you create a lot of them per frame it can add up and the garbage collector will spend a lot of time keeping up and you will notice higher memory upkeep.
Note neither of these are leaks since the garbage collector takes care of most dumbassery you throw at it, including memory islands. In case you're working with love.physics or other framework modules it is possible to make the collector cry and hide things inside userdata objects which it will not clean up, such as the setUserData() method in some physics objects.
Unless your program crashes due to insufficient memory over time, it's likely your code just produces a lot garbage on the side.
Re: Memory Leak in only two lines
Posted: Fri May 02, 2014 10:55 pm
by Ref
Guess my post got eaten by Azhuker.
Have run into imagedata => image each frame problem.
Garbage collection only seemed to remove last image created so memory use remains high and CPU use very high.
Found adding collectgarbage( 'collect' ) after each draw kept memory and CPU use low but on exiting program the window would close but the program would keep running causing the computer to hang.
Re: Memory Leak in only two lines
Posted: Sat May 03, 2014 1:12 am
by Inny
Lua's own stack frames are heap-allocated and garbage collected. But no, this isn't a leak, this is regular operating behavior for Lua. What should concern you is not how much memory lua is allocating before it performs a garbage collection cycle, but rather how often the collection cycles are happening. If Lua has to garbage collect faster than your framerate, then the time spent processing the collection is time taken from your code, which means you'll experience a lower framerate.
Re: Memory Leak in only two lines
Posted: Sat May 03, 2014 1:40 am
by Ref
My experience is that if too much memory is being used before collection, the program slows down and eventually Love starts throwing random error messages. Forcing garbage collection avoids these problems in this situation.
(Possibly in part due to my use of 4000 x 3000 images.)
Re: Memory Leak in only two lines
Posted: Sat May 03, 2014 1:48 am
by slime
Lua doesn't know about the real space in memory (and Video Memory) taken up by LÖVE's objects like Images, Fonts, etc. As far as Lua's garbage collector knows, all LÖVE objects are only a few bytes each - so the garbage collector doesn't prioritize them when it sees a buildup. But it will still eventually collect them and free the memory used by them, as long as you have no more references to them in your own code.
In general, you should try to avoid having multiple gigabytes of data (a single 4000*3000 image takes up 45MB of RAM and at least 45MB of VRAM, and won't even work at all on some older GPUs.)
Re: Memory Leak in only two lines
Posted: Sat May 03, 2014 3:13 pm
by Ref
AMmmm. I only experienced the garbage collection problem when I abuse LÖVE by median stacking 10 4000 x 3000 images to remove noise and moving objects from photographs.
All the imagedata for the 10 phootographs remains loaded thought out the process but I wanted to see the progress of the conversion sooo I converted the imagedata each frame to an image to show what's going on (rather than starring at blank screen while its doing its thing).
The continual generation of new images resulted in massive garbage which Lua doesn't seem to be able to automatically remove ( it only seems to try to remove the last image and eventually gives up with a random LÖVE error message.)
If I force garbage collection after each image is drawn, memory use remains constant, CPU use low, and no errors are encountered.
So, what's the problem?
Sometimes when I exit the program, the display window disappears but something keeps running which slows down the computer and when I turn off my computer requires Windows 7 to force a shutdown.
Moral - when you do something weird, you may get what you want but expect the unexpected.
Re: Memory Leak in only two lines
Posted: Sat May 03, 2014 10:22 pm
by verilog
Ref wrote:
If I force garbage collection after each image is drawn, memory use remains constant, CPU use low, and no errors are encountered.
This might be a silly question but, did you remove each image reference before garbage collecting?
Re: Memory Leak in only two lines
Posted: Sun May 04, 2014 2:07 pm
by Ref
image = nil failed to prevent garbage accumulation.
Found that I had to force garbage collection to eliminate the old images.
Re: Memory Leak in only two lines
Posted: Mon May 05, 2014 12:52 am
by WetDesertRock
What I found is that my games memory footprint would reach much higher levels than what I expected before dropping sharply. Perhaps you aren't watching for long enough?