| > Delayed destruction (either on another thread or batches) removes the possibility of safely using RAII via finalizers No, it doesn't in general. Delayed destruction can be used selectively only for these object graphs that could cause large batches of deallocations, and only once you find by profiling that you really have a problem. Most object graphs are not like that, so don't penalize the average case for the edge case you might even not have at all. You can still use synchronous deallocation on the objects where immediate deallocation is needed. Secondly, I bet delayed deallocation on a background thread happens a lot sooner than waiting for the next GC to happen and to call the finalizers (which may never happen). With delayed deallocation the system knows how much there is to deallocate. With tracing GC there is no such knowledge until tracing is over. > Most modern implementations of refcounting end up having a cycle collector, anyway, which also means you can end up unexpectedly paused, removing another touted advantage. That's why Rust doesn't have a default cycle collector. Reference cycles are IMHO a non-issue in practice. There is no point in paying for cycle-collection by unpredictability of the whole program, when it helps only with edge-cases. > In general, GC implementations (including initially-refcounting) tend to converge over time in both performance and features. I'd frame it differently: all-purpose one-size-fits-all memory management solutions are almost universally suboptimal and easily beaten by solutions which give more control in programmer's hands. Rust is about providing that control about fine details and giving you a set of handy tools. The toolset might be slightly harder to learn initially due to borrow checker and lifetime rules, but over time I didn't notice any productivity hit from that (actually quite contrary, but this is a different topic). And somehow, even without me doing any heavy optimisations, my Rust programs tend to use 100x less memory and perform way faster than my Java programs. How can it be explained, when I have much more Java experience than Rust experience? |
Any double-linked structure makes it very much an issue. And before you reply with "who uses linked lists anyway", consider the publisher/listener pattern: a publisher has the list with its listeners, a listener usually knows what publisher(s) it's subscribed to.