Also, to answer your query, Rust uses unique pointers (the equivalent of std::unique_ptr in C++0x) for inter-thread communication. When the unique pointer goes out of scope, its memory is immediately freed (since it was the only owner of the data). And since the data has only one owner, it's data-race-free.
Cool on Rust, though! Thanks for the info!
Reference counting is also not even that great for shared memory multithreading. The (atomic) increment/decrement operations typically cause lots of cache invalidation, so you'll get a slowdown even for immutable objects.
The alternatives are either (a) avoiding shared state; (b) strong lifetime management such that you make sure one parent thread owns all of the data that its child threads are going to use; (c) concurrent GC; (d) pretending it's not a problem like Go does and doing stop-the-world GC.
Thanks again folks!
Interesting point about the cache invalidation, though. I wonder if we'll see chip vendors going out of their way to improve performance and invalidation when using atomic ops.
They already put a lot of effort into making this stuff as efficient as possible - the fact that Intel is going in the direction of hardware transactional memory indicates to me that they don't think the bus locking/cache snooping approach scales, and I can't say I'm surprised.
(not a Objective-C dev, so don't know)
The exception is the autorelease pool, which gets dumped at the end of every turn of the event loop. You can promote or demote objects from the autorelease pool at will.
Anyway, the biggest problems with Obj-C memory management are (a) you can't allocate objects on the stack, so you're forced into using the autorelease pool for stuff, and (b) you can promote or demote objects from the autorelease pool at will, which means that even the autorelease pool has to malloc, thus you don't get the nice benefits of super-cheap bump allocation that C++ arenas (or a generational GC's nursery) buy you.
Anyways, thank you for the information!
With reference-counted smart pointers, you can guarantee that objects immediately go away once they leave scope, and that you can pass them around between threads without worrying too much about a thread forgetting to delete them. No other language has such easy support for doing something like that without relying on a background memory-management mechanism (at least that I'm aware of--I'd like to hear about it if you know one!).