Incremental garbage collection
Gregor Mückl
gregormueckl at gmx.de
Sat Jan 29 17:32:32 UTC 2022
On Thursday, 20 January 2022 at 23:56:42 UTC, Chris Katko wrote:
> I just found out that Unity has incremental garbage collection.
> I didn't know that was a possibility for GCs.
>
> https://docs.unity3d.com/Manual/performance-incremental-garbage-collection.html
>
> I'm just curious what the D language community's thoughts are
> on it. The tradeoff is: For
> a longer total time / lower throughput, you reduce stress on
> individual frames which prevents hiccups. That's pretty darn
> important for games and soft/hard real-time systems.
>
> Is that an option on a hypothetical level, for D? Or does D's
> language design preclude that. I recall some sort of issue with
> using Java/C#/whatever's garbage collector because it would
> have to insert memory barriers into D to work or something like
> that.
>
> Also, it's hard to find one specific place for "news" regarding
> D's garbage collector development and "omg we deleted
> everything GC from the standard library" projects. Are there
> any major updates on those fronts?
Just to add to this for completeness sake: a while ago I spent a
few hours digging through Uneal Engine source code to understand
their GC algorithm. It's a peculiar and interesting take on
iterative, precise, conservative garbage collection:
- First of all, UE4 has precise runtime reflection information
for all data types that are handled via the GC (everything
derived from UObject - which is mostly game logic code). Heap
scans are optimized aggressively based on this data. Pointers are
regular naked C++ pointers without any additional magic. They
need to be annotated for the custom preprocessor that generates
the reflection data, but that's it. The C++ code touching these
pointers is plain old code using naked pointers. No hidden
wrappers there.
- The algorithm is basically mark and sweep with a couple of
awful situational hacks that stem from weird engine subsystem
interactions. I'll gloss over those. The GC performs a multistep
GC process. Each frame, the engine prompts the GC to run one step
in a stop-the-world fashion.
- Each step, the GC can either run an *entire* mark phase or a
single step of the sweep phase. The mark step is always run in
its entirety, never in multiple steps. The sweep phase is broken
up into steps that free a limited number of marked objects in
each step. The rest is deferred to the next step. When sweep
phase is done, the next GC step will be a new mark phase.
IMO, this is a very pragmatic approach. But for the runtime to be
truly bounded, the heap size needs to be bounded, too. I assume
that this works for UE4 because for most games using the engine,
the number of objects involved in the game logic at any point is
fairly small (mostly ~ a few hundred). Stopping the world for the
mark phase is also a major simplification. This avoids the
overhead typically incurred by GC algorithms that do incremental
marking. Also, GC references can be treated just like regular
pointers.
I don't know how the D garbage collector runtime is split between
mark and sweep phases. If the sweep phase is indeed the slower
phase, an option to have that run iteratively might be enticing.
I would naively assume that this would be lower hanging fruit
compared to a generational and/or concurrent GC. But then again,
I don't have a need for any of that at the moment.
More information about the Digitalmars-d
mailing list