3 ms·
As sibling comment mentioned, reference counting is very much non-predictable in latency. If you want predictable, you want your GC to run either in constant t
by p_l 2y ago
As sibling comment mentioned, reference counting is very much non-predictable in latency.
If you want predictable, you want your GC to run either in constant time slice, or an upper-bounded timeslice.
Deferred refcounts can become quite complex if you want to avoid "I have just released last reference to something that contained a lot of other referenced" (there are some funny threads where Rust users discover that they sometimes need to spin an extra thread to not have effective "stop the world" XD).
So instead common approach is tracing GC with some form timesliced running collector, guaranteeing that time taken from mutator will be upper-bounded. For example, instead of stopping the world, concurrent GC will usually only require a synchronization point. Sometimes it also means that the collector will be given explicit timeslice to ensure that there's certain amount of work being done - it's all tradeoffs based on how much throughput and latency you want.
You can speed up tracing collectors through things like escape analysis and 1bit reference counting (for example, you set a bit if a new reference is passed outside of current scope, every object without bit set can be assumed to have all referenced contained in given scope, etc).