Well, ever seen a C++ program that seemingly finished execution, but still haven’t exited?
That’s shared pointers recursively freeing up their reference trees. There is a great paper showing that RC tracks object death, while tracing GCs track object “liveness”, so its essentially two sides of the same coin.
As for RC, sure, at compile time many of the work can be omitted, but atomic writes needed for the counters are fundamentally slow operations on modern architectures.
You can do reference counting without making it atomic, by prohibiting sharing across threads. It’s not fundamentally required. See Rust’s Rc, for example.
That’s shared pointers recursively freeing up their reference trees. There is a great paper showing that RC tracks object death, while tracing GCs track object “liveness”, so its essentially two sides of the same coin.
As for RC, sure, at compile time many of the work can be omitted, but atomic writes needed for the counters are fundamentally slow operations on modern architectures.