Automatic reference counting means adding retain and release messages automatically; there most certainly is a runtime hit, and that's on top of the usual memory allocator costs, which can be quite high. A good compiler can eliminate some of those retain/release calls.
Sure, but I would assume any manual memory management system worth it's salt is doing retain/release. Most of the C++ big libraries do it.
Furthermore, because of deallocation cascades, a release message in such schemes can have a very high latency (don't know whether Apple tried to add workarounds).
- Deallocation cascades are inherent in memory management. Neither reference-countless memory management nor garbage collection can avoid it. So I'm not sure what the point here is.
- As far as latency on dispatches, Apple is using tagged pointers (http://en.wikipedia.org/wiki/Tagged_pointer) which is using some room in the pointer for holding the reference count. In practice, this means means there is practically no latency for messing with the retain count.
And, of course, ARC has the same problems with circular references that regular reference counting has.
Which is also a problem with Garbage Collection...
Reference counting is a mediocre memory management scheme at best; people use it in C-like languages because they don't have a choice. It is inferior in just about every way (runtime overhead, latency, memory utilization) to a good garbage collector.
I don't see how it is at all. Results are instant. Overhead is far less. Pretty much every claim here needs citation. It's hard to see how an entire process constantly analyzing object references is less overhead than pre-handling those references. Memory utilization? I have to burn a bunch of memory on a garbage collection process, and then watch my memory climb and then drop off a cliff constantly while I wait for the garbage collection to run, while retain counted count generally stays with a pretty stable allocation count because it's instantly computed. Puh-lease.
I saw your claim below that GC is identical to retain/release in behavior. It really is not. If I clear out a reference in Obj-C or any other retain/release language, the memory is instantly freed. In Java, I have to wait for another run of the garbage collector, which can take a while unless I manually trigger it. Yes, YOU don't have to wait for anything in the code. But ignorance is bliss.
Here's basically the comparison I'd use: Retain/release is like having an incinerator you throw your garbage into. Garbage collection is like... well... having a garbage truck. In both cases when I'm writing code I can just throw things away in my trash bin and pretend it's not there. With retain/release/an incinerator, the memory is actually gone as soon as I throw it in the trash bin. With garbage collection, I've thrown it in the bin and forgotten about it, but that doesn't change that the trash will continue piling up until the trash guy comes, which may still be a bit away. The large amount of piled up trash is also a problem, and actually makes the cascade problem you were concerned about with retain/release WORSE. Instead of a few cascade relationships being dealloc'd at once, all the dereferenced objects are going to pile up, wait for the garbage collector, and then the garbage collector is going to have to pour through thousands of relationships all in one go, causing the program to come to a halt while everything waits for the garbage collector to catch up. I've had to clean up a few Java messes that had that problem by manually firing the garbage collection to spread out the load.