[???] GC can't keep up while the game is paused

Mon Nov 02, 2020 7:14 am

No idea when this showed up, but it has probably been around for a long time.
Basically, when the game is paused, GC collection slows down to a crawl. This means that, if a normal menu allocates classes constantly, the GC never collects memory fast enough to offset the constant increase, and you end up with a net increase in RAM usage.

You can reproduce this with Nash's PDA starter kit:
  • Clone the repo or download the source Zip and launch GZDoom while using the entire folder as a file, with Doom 2 as the IWAD.
  • Start the game and do "stat gc" in the console.
  • Pick up the items in front of you, then press the Use Inventory key on the item you get.
  • Click any of the entries in the list.
  • Memory allocations will now be too fast for the GC to keep up with. Once "Alloc" reaches "Thresh", it'll be stuck in the Sweep phase.
If you add "menuactive = OnNoPause;" to the Init function of PDAMenu (In "zscript/PDAMenu.zc"), the issue never pops up. Once Alloc reaches Thresh, it starts collecting dead objects just fine.
Doing "gc pause 1; gc stepmul 400000" in the console also seems to help while the game is paused.

In general, this is a pretty serious issue that needs to be fixed. There's no reason for GZDoom to slow down the GC like this when the game is paused.

Re: [???] GC can't keep up while the game is paused

Mon Nov 02, 2020 8:05 am

Also confirmed to happen with RRWM's HUD, which uses a widget system that involves creating a lot of small objects on each draw pass. Guess I never noticed this because I usually minimize the game instead of pausing it, and also maybe because I have 32 GB RAM. :roll:

Re: [???] GC can't keep up while the game is paused

Wed Nov 18, 2020 6:53 am

Since this effects ZForms so much I've looked into this and the cause is fairly simple - the GC is normally called via CheckGC once per thinker per tick, and while the game is paused, thinkers aren't ticked, so the GC is never called apart from a few scattered calls to CheckGC (which are the cause of this bug not happening if stepmul is set to a very high amount). A simple solution here is just to call GC::FullGC before the early return in line 112 of p_tick.cpp. I'm not sure if there's a better solution but in my testing this doesn't result in any major performance problems (especially since the game gets locked to 35 FPS when the game is paused anyway).

Re: [???] GC can't keep up while the game is paused

Tue Nov 24, 2020 7:32 pm

I've PR'd the fix described above here: https://github.com/coelckers/gzdoom/pull/1242

Re: [???] GC can't keep up while the game is paused

Sat Dec 12, 2020 5:12 am

What about this? It fixes the problem:
Code:
diff --git a/src/p_tick.cpp b/src/p_tick.cpp
index 7253eafbe..8b74e41ec 100644
--- a/src/p_tick.cpp
+++ b/src/p_tick.cpp
@@ -107,6 +107,8 @@ void P_Ticker (void)
                ac->flags8 &= ~MF8_RECREATELIGHTS;
                ac->SetDynamicLights();
             }
+            if (!(ac->ObjectFlags & OF_Released))
+               GC::CheckGC();
          }
       }
       return;

Edit: i've tweaked it a little.

Re: [???] GC can't keep up while the game is paused

Sun Dec 13, 2020 4:39 am

I made another PR (it's been closed BTW) and it fixed the issue with Nash's PDA Starter kit but this not only happens when the game is paused. I've tried RRWM 1.2.3.7 and memory usage keeps increasing even when the game is running, with my fix it decreases when you pause the game tough. So may be the issue with the HUD it's not a bug and just there are too many objets being created.
https://github.com/coelckers/gzdoom/pull/1251
https://bitbucket.org/Player701/rrwm/do ... -v1.2.3.7z

Re: [???] GC can't keep up while the game is paused

Sun Dec 13, 2020 5:29 am

In my RRWM playtesting sessions the game never crashed during gameplay, and I never noticed any abnormal memory usage. I've just tested again with GZDoom 4.5.0 and RRWM 1.3.0a, and memory usage does seem to go higher and higher if I just fire up a level and do nothing. But as soon as I start running around, opening doors, shooting at enemies etc., it eventually stabilizes and only starts increasing again while the game is paused (and resets to normal once un-paused).

Re: [???] GC can't keep up while the game is paused

Sun Dec 13, 2020 5:43 am

Let me repeat: I think placing the additional calls in P_Ticker is dead wrong because this is not the correct place for paused gameplay, Also, repeated calls to CheckGC only are effective if there have been additional allocations in the mean time. So this must be done in a place that a) gets called repeatedly and b) is at least somewhat sensitive to object allocation frequency.

Re: [???] GC can't keep up while the game is paused

Sun Dec 13, 2020 1:50 pm

Player701 wrote: memory usage does seem to go higher and higher if I just fire up a level and do nothing

If you don't interact with the actors memory usage skyrockets until the system freezes (i was so pissed the last time that i added an optional ram safeguard to abort), alerting the monsters is enough to prevent it. So this issue is even more serious than it seemed initially.
Graf Zahl wrote: repeated calls to CheckGC only are effective if there have been additional allocations in the mean time

For me it works when the game is paused, my code AFAIK iterates through all actors whose objects have not been released by the GC. I could not find a better place. But now it also happens when the game is not paused.

Re: [???] GC can't keep up while the game is paused

Sun Dec 13, 2020 4:14 pm

Yes, it works - but not by design but by happenstance. You still gobble up all the allocations from a single frame which in bad cases can cause problems. If you want to do it like this, a single CheckGC call in the main loop would suffice and produce the exact same result as this.

Re: [???] GC can't keep up while the game is paused

Mon Dec 14, 2020 4:33 am

Not really but i don't know how to fix this, the problem is that the GC can't keep up when thinkers don't think, with the game being paused or not. Could we do something about that in the menu ticker?

Re: [???] GC can't keep up while the game is paused

Fri Dec 18, 2020 4:02 pm

One thing to note here for the writers of mods that this effects - ZScript structs aren't allocated via new(...) so they aren't subject to this. I've entirely fixed this issue locally for the next version of ZForms by converting the AABB class to a struct. It's a bit less nice to use because structs are a bit limited in ZScript but it works well enough, and causes no memory issues. Not a fix to the root cause but this seems like it'll fundamentally be a hard issue to fix so I feel like pointing it out.