> We don't want Garbage Collection to the contrary we want reference counting. Reference counting is the best compromise between handling memory manually and using GC ala Java. I would argue that the mental strain for the programmer is equal for reference counting(at least with ARC) to that of GC. However Reference Counting is extremely lightweight.
I used to think that, until I started to spend more time on modern GC platforms like Java and .NET. It's impressive how performant a good generational garbage collector can be. For many business applications (i.e., not the kinds of workloads you'll see being simulated by popular benchmarks) a good generational GC can even improve performance thanks to improved locality of reference. I think a lot of us don't fully appreciate the cost of a cache miss.
Speaking of, I'm not sure a lot of us fully appreciate the cost of synchronization, either. It's one big reason why I'm not convinced that reference counting is particularly well-suited to concurrent programming, since it turns a really commonplace operation (retaining a reference to an object) into a synchronization point in the program. There's a non-trivial cost associated with that. You could avoid repeatedly stalling the CPU by being very careful about not sharing objects among threads, but I don't think most developers can reasonably be expected to make a habit of that in practice.
> Speaking of, I'm not sure a lot of us fully appreciate the cost of synchronization, either. It's one big reason why I'm not convinced that reference counting is particularly well-suited to concurrent programming, since it turns a really commonplace operation (retaining a reference to an object) into a synchronization point in the program. There's a non-trivial cost associated with that.
This is actually a problem for both. Simple implementations of AGC have to stop the world to scan at least the roots, and probably even a bit more than that, because there are significant ABA problems. There are ways around this, but as far as I know the only environment to use any of the really good ones is the JVM, because it's hellishly complex. I don't know that there is anything that doesn't stop the world for at least a couple of ns, though.
There are also solutions to it for reference counting. They involve using thread local reference counts and briefly stopping the world to reconcile the counts. I believe [1] describes this algorithm.
And once you get there, and start dealing with cycle detection, the difference between the two approaches starts to look a lot smaller. There's a paper on this too. [2]
I used to think that, until I started to spend more time on modern GC platforms like Java and .NET. It's impressive how performant a good generational garbage collector can be. For many business applications (i.e., not the kinds of workloads you'll see being simulated by popular benchmarks) a good generational GC can even improve performance thanks to improved locality of reference. I think a lot of us don't fully appreciate the cost of a cache miss.
Speaking of, I'm not sure a lot of us fully appreciate the cost of synchronization, either. It's one big reason why I'm not convinced that reference counting is particularly well-suited to concurrent programming, since it turns a really commonplace operation (retaining a reference to an object) into a synchronization point in the program. There's a non-trivial cost associated with that. You could avoid repeatedly stalling the CPU by being very careful about not sharing objects among threads, but I don't think most developers can reasonably be expected to make a habit of that in practice.