How do you really tell if your game has a memory leak?

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.
User avatar
pgimeno
Party member
Posts: 3588
Joined: Sun Oct 18, 2015 2:58 pm

Re: How do you really tell if your game has a memory leak?

Post by pgimeno »

BrotSagtMist wrote: Mon May 20, 2024 11:04 pm This is the very definition of a memory leak.
And of course its not anymore if you call garbage collect, i mean.... thats the point.
What are you trying to say here?
A memory leak consists of memory that is never released. The difference with what I'm saying is that garbage collection would eventually occur if you had enough memory to hold those temporary objects until garbage collection occurs.

Imagine a program that generates garbage, filling up to 20 GB before the garbage collector kicks in and cleans up the objects. Would you say that this program has a memory leak in a 16 GB computer, but not in a 32 GB computer? I think that's ridiculous. Either the program has a memory leak. producing objects that are never released, or it doesn't; it can't depend on the RAM present in the computer it's run on.
User avatar
zorg
Party member
Posts: 3449
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: How do you really tell if your game has a memory leak?

Post by zorg »

(Technically it depends on the maximum allowed commit size, not the physical RAM amount, but i digress)
I do tend to agree though, i'd rather call something a memory leak only if it's something you cannot ever reclaim without closing the application; automatically GC-d stuff would eventually be GC-d, manually reserved stuff (e.g. with FFI then you throwing away the pointer, or just forgetting to free it) won't.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
BrotSagtMist
Party member
Posts: 636
Joined: Fri Aug 06, 2021 10:30 pm

Re: How do you really tell if your game has a memory leak?

Post by BrotSagtMist »

Even if your entire program is just

Code: Select all

Font = love.graphics.newFont( 12) 
Font = love.graphics.newFont( 21) 
In my book thats a memory leak, those two lines cause a memory leak.
Because it fits the definiton of "not freeing unused data". And thats the whole thing, this line, it fits so it is. No greyzones for me. If a GC can solve that or not is not the point, because there is no GC in these two lines.

You can run it as fancy loop if you need proof that the construct will eventually crash your computer

Code: Select all

X=1
function love.update()
 X=X+0.1
 Font = love.graphics.newFont( X) 
 if X>200 then X=1 end
end
function love.draw()
 love.graphics.setFont(Font)
 love.graphics.print(X)
end
obey
MrFariator
Party member
Posts: 525
Joined: Wed Oct 05, 2016 11:53 am

Re: How do you really tell if your game has a memory leak?

Post by MrFariator »

Doesn't crash on my system, though with a slight asterisk: You can change lua's garbage collector's parameters with:

Code: Select all

collectgarbage("setpause", 50) -- sets how much the garbage collector needs to wait before doing its thing. Smaller value means less wait time. Default is 100?
collectgarbage("setstepmul", 400) -- sets how much the garbage collector clears up in a 'step'. Higher value means more cleaning gets done. Default is 200.
With the default garbage collector settings your example leads to memory usage ballooning (sometimes my machine caught up and cleaned it, other times it took a fair while and consumed GBs of ram), while with the settings above it is able to keep it at bay. If you expect your program to generate a bunch of garbage (like maybe you're churning through a bunch of data, and creating a lot of intermediate objects that get discarded later), you can always adjust the gc to better suit your needs. This approach may not work for games (due to gc steps often causing stutters), but it can work for any applications that may use a lot of memory. As such, this is kind of a space leak issue that can be controlled, though obviously you should not be creating things like fonts every frame.
User avatar
BrotSagtMist
Party member
Posts: 636
Joined: Fri Aug 06, 2021 10:30 pm

Re: How do you really tell if your game has a memory leak?

Post by BrotSagtMist »

I read that as "the man is not dead, he would be alive if his heart would be beating"
Yea no shit, if you adjust GC its not a problem, but then you also dont use the same code. And the point is of this code having a problem, not the _fixed_ one.

In other news, this crashes my computer and i am really angry OOM killer doesnt bother to do its job. I wonder why that is.
obey
User avatar
pgimeno
Party member
Posts: 3588
Joined: Sun Oct 18, 2015 2:58 pm

Re: How do you really tell if your game has a memory leak?

Post by pgimeno »

BrotSagtMist wrote: Tue May 21, 2024 1:16 pm Even if your entire program is just

Code: Select all

Font = love.graphics.newFont( 12) 
Font = love.graphics.newFont( 21) 
In my book thats a memory leak, those two lines cause a memory leak.
Because it fits the definiton of "not freeing unused data". And thats the whole thing, this line, it fits so it is. No greyzones for me. If a GC can solve that or not is not the point, because there is no GC in these two lines.
In my book that's not a memory leak, because the interpreter frees the memory it used when it finishes, including the allocated objects.
BrotSagtMist wrote: Tue May 21, 2024 1:16 pm You can run it as fancy loop if you need proof that the construct will eventually crash your computer

Code: Select all

X=1
function love.update()
 X=X+0.1
 Font = love.graphics.newFont( X) 
 if X>200 then X=1 end
end
function love.draw()
 love.graphics.setFont(Font)
 love.graphics.print(X)
end
Well, for me it doesn't. According to top, memory keeps growing until VIRT reaches 8,364,896 and RES reaches 7,397g, then VIRT it goes back to 8,340,316 and RES to 7,374g and then it stays in that loop. I have 32 GB in case that's important. So no, for me that's not a memory leak, it just imposes a minimum RAM requirement for the program to work.
RNavega
Party member
Posts: 280
Joined: Sun Aug 16, 2020 1:28 pm

Re: How do you really tell if your game has a memory leak?

Post by RNavega »

BrotSagtMist wrote: Tue May 21, 2024 1:16 pm You can run it as fancy loop if you need proof that the construct will eventually crash your computer
Regardless of what people want to call this, it does sound problematic as you have to explicitly call collectgarbage() before the program crashes, which isn't obvious if you expect the garbage collector kicking in on its own after a while.

Where could this constant font reloading problem happen? I don't think window resizing would cause this, as the event is only emitted once the user releases the mouse. But saying that it did, implementing something like event throttling and/or de-bouncing, as people do for JavaScript, would be a remedy.
User avatar
pgimeno
Party member
Posts: 3588
Joined: Sun Oct 18, 2015 2:58 pm

Re: How do you really tell if your game has a memory leak?

Post by pgimeno »

RNavega wrote: Tue May 21, 2024 9:37 pm Regardless of what people want to call this, it does sound problematic as you have to explicitly call collectgarbage() before the program crashes, which isn't obvious if you expect the garbage collector kicking in on its own after a while.
Not really. Just adding a line before newFont, like the following, solves the problem:

Code: Select all

if Font then Font:release() end
Font = love.graphics.newFont(X)
You just have to be aware that dismissing a potentially big object is problematic, and release those.

If you don't know what objects cause the memory growth and don't want to spend time digging into it, adding a single collectgarbage() anywhere in love.update() will suffice. It doesn't even have to be right after an object is dismissed. But depending on the size of the project, a full garbage collection cycle may take a while. In T2R I found that collectgarbage("step", 2) sufficed (back then we didn't have Object:release()).
User avatar
BrotSagtMist
Party member
Posts: 636
Joined: Fri Aug 06, 2021 10:30 pm

Re: How do you really tell if your game has a memory leak?

Post by BrotSagtMist »

Well, for me it doesn't. According to top, memory keeps growing until VIRT reaches 8,364,896 and RES reaches 7,397g, then VIRT it goes back to 8,340,316 and RES to 7,374g and then it stays in that loop. I have 32 GB in case that's important. So no, for me that's not a memory leak, it just imposes a minimum RAM requirement for the program to work.
It takes a few minutes on my 4gb system. And top doesnt properly show it, i can not explain the behaviour but this code will crash all my systems veryfiying that this code does in fact not release its memory.
Not really. Just adding a line before newFont, like the following, solves the problem:
So youre saying, its not bug because if you use a totally different code it works? I mean, what?
RNavega wrote: Tue May 21, 2024 9:37 pm Regardless of what people want to call this, it does sound problematic as you have to explicitly call collectgarbage() before the program crashes, which isn't obvious if you expect the garbage collector kicking in on its own after a while.
Yea thats what i am trying to get here at. These lines do not work as we expect lua to work.
Where could this constant font reloading problem happen?
In my case, my text boxes are scaled in a way that their text content stays the same over all its sizes.
So a box has say 10 lines in it regardless of how big the window is.
Now have a dozen of such boxes in a window and you want this window to be able to properly resize it can grow to use a lot memory.
But since normal people do rarely change their window size such error would probably go undected for years.
I cought it because i liked my scaling so much i shook the window like an unwanted baby for half an hour and it rewarded me with a freeze.
obey
User avatar
pgimeno
Party member
Posts: 3588
Joined: Sun Oct 18, 2015 2:58 pm

Re: How do you really tell if your game has a memory leak?

Post by pgimeno »

BrotSagtMist wrote: Tue May 21, 2024 10:59 pmIt takes a few minutes on my 4gb system. And top doesnt properly show it, i can not explain the behaviour but this code will crash all my systems veryfiying that this code does in fact not release its memory.
I left it running for over an hour, and the love executable didn't reach 8 GB according to top. I also monitored global memory usage and it also stopped growing when the memory reported by top did, and my system didn't crash. So, your code happens to be a perfect example of what I was saying earlier. It only crashes in computers which don't have enough RAM for holding the dismissed objects that stay in memory, waiting for the GC to release them. I don't call that a memory leak: it delays releasing the RAM, but it eventually gets to it if you have enough.

BrotSagtMist wrote: Tue May 21, 2024 10:59 pm
Not really. Just adding a line before newFont, like the following, solves the problem:
So youre saying, its not bug because if you use a totally different code it works? I mean, what?
No, I'm saying that it's not a bug because it's the way that Lua works, and there's nothing that Löve can do about it, besides providing methods like Object:release() to help the programmer do something about it. There's a reason for the yellow warning present near the top of many Löve API wiki pages, including love.graphics.newFont, which recommends to cache the created objects to reuse them instead of creating new ones over and over. A memoizing function would probably help in this case as well.

BrotSagtMist wrote: Tue May 21, 2024 10:59 pmYea thats what i am trying to get here at. These lines do not work as we expect lua to work.
But that's Lua's fault, because a single Lua object can take memory outside its control and make the default GC settings inadequate. And programmers need to be aware of that problem.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 8 guests