4 ms·
Generally speaking if a .NET game has GC pauses, it's probably because they didn't try. You can represent most game state using structs and arrays without signi
by kevingadd 4y ago
Generally speaking if a .NET game has GC pauses, it's probably because they didn't try. You can represent most game state using structs and arrays without significant ergonomics problems, and your GCs for the classes you do heap allocate will be much shorter if you design your data structures to be quick to trace.
Things were different for Unity games using the Boehm collector though, since it's a conservative non-generational collector that as a result is very slow to collect and collects more frequently. That's why you saw a lot of frequent pauses in Unity games (my understanding is they no longer use Boehm).
The game I'm currently working on GCs maybe 1-2 times per minute and the pauses are short enough that it doesn't drop frames, despite the fact that it frequently allocates strings and uses 'async Task' extensively. If you tune the collector settings you can control this even more, and you also have the option to manually force GCs to happen while the game is waiting for vsync, which hides them further.
Visual Studio has a built in allocation profiler that can help if you're looking to optimize your games for fewer GCs, and to make tracing faster what you want to do is avoid having any reference types in your struct arrays (use handles instead), which will let the GC skip tracing your big arrays of structs entirely. So for example the big tables of draw calls I use refer to textures by numeric handle instead of reference, which means I can have a 50mb table without making GCs slower.
Using handles instead of references also means that copying the struct doesn't require write barriers, which will boost your overall perf a bit.