Also every single graphics application that uses Metal or DirectX, relies on reference counting as GC algorithm.
Oh shit…
Garbage collectors aren’t magical black boxes with no levers, and you can use them how you like.
You address performance problems relating to GC the same as you do anything else: measure, analyze, optimize, repeat.
Heck, there is a whole cottage profession of experts who get called into fix GC related performance issues with Unity.
A cottage industry is built around making rocks look good too. Is that an indicator that games are good or bad at making rocks?
Can you quantify and elaborate more how much GC is an issue for something like Unreal engine?
How do you "optimize" the GC away after you wrote your entire database server in a language that uses it?
But the most naive example any language supports is simple object pooling.
Then more fancy, zero allocations tasks in C# https://github.com/cysharp/unitask
(Even though, no, that's not typical. That's a tiny minority of them.)
Once you measure, you'll find a small fraction of the code is taking a large fraction of the time. When you zoom in on trouble-spots you may find, e.g. that the GC is taking the time (or you may find something else entirely is taking the time). If it's the GC, you might look and see, e.g., that it's spending its time tracing the objects in the 100K node graph you're creating several times a second, and realize you could, e.g., create it once and simply keep reusing it. Perhaps it might be as simple as using removeAll(keepingCapacity: true) instead of removeAll() (a Swift example).
The superficial details differ, but you generally just want to understand what the GC is working so hard on and lighten its load. If you haven't been measuring and optimizing throughout, there are almost certainly easy-to-pluck, low-hanging fruits, ripe for the taking.
Where GC means any kind of GC algorithm from CS point of view.