4 ms·
I was wondering, why not use ARC, as in C++ and Obj-C?
by z92 11y ago
I was wondering, why not use ARC, as in C++ and Obj-C?
- mehrdada 11y agoReference counting generally suffers from the cyclic reference problem, e.g. if you lose a reference to a doubly-linked-list, the entire data structure leaks and won't get freed. In Obj-C, this problem is tackled via manually annotating some pointers as "weak", explicitly (and you have to be extra careful with them). There are less fundamental issues as well, like high contention on the reference count in highly parallel environments, and more memory fragmentation compared to a compacting garbage collector. Also, memory allocation tends to be faster on a compacting garbage collected heap (simply increment the heap pointer instead of searching for a large enough available block). Additionally, freeing memory when things run out of scope cause challenges when optimizing code, like making it more difficult to optimize function invocations that otherwise would have been eliminated as tail calls with a garbage collector. In practice, in some cases, the cost of a tracing garbage collector might be well worth when you amortize it over the lifetime of the program, compared to keeping track of reference counts at runtime.
- frnzkfk 11y agoThe classic problem: cycles. Either you make the programmer manually deal with cycles via weak references, which can be error prone and allow memory bugs to creep in, or you have a secondary GC to collect cycles. The first one increases programmer complexity and the second one increases implementation complexity, which are, respectively, the first and second things Go attempts to avoid. There's also the issue that ARC vs. GC is a tradeoff between CPU overhead and memory overhead, and that in the scenarios Go was initially designed for (Google's servers) memory is much cheaper.
- millstone 11y agoThe Go FAQ addresses this: http://golang.org/doc/faq#garbage_collection http://golang.org/doc/faq#garbage_collection Upon re-reading, it's distressing to hear that the GC latency has been raised from "not significant" to "low."
- zurn 11y agoIn addition to the cyclic references problem, rc has a high constant overhead (memory traffic from constant manipulation of rc fields) and a problem with pauses (cascading deallocations). Also it precludes efficient shared memory concurrent access of managed objects.
- mzl 11y agoSimple reference counting is quite possibly the worst possible choice for automatic garbage collection, especially since it is so intuitively appealing. The common objection is that cycles are hard to handle; leading to either a broken behaviour (leaking garbage) or adding complicated cycle detection (negating the premise of a simple solution). Apart from cycles, reference counting has several other issues. Some of my pet objections are: * The need to add a mutable field to every object increases the active memory foot-print significantly (especially bad for caches). * The frequent updates to that field must be done using atomic operations if the objects may be accessed by different threads (even though the objects themselves may be immutable). * The updates to the reference field trashes the caches in a multi-core processor. * The amount of work done managing these updates can easily become a significant part of the run-time of the program, in some cases dwarfing the actual work. * Uncontrolled arbitrarily long pauses will happen when cascading deletions happen. There are really cool and smart algorithms that make reference counting much better, but then the appeal of a simple natural algorithm for collecting garbage has come and gone.
- fauigerzigerk 11y ago>There are really cool and smart algorithms that make reference counting much better, but then the appeal of a simple natural algorithm for collecting garbage has come and gone. That's probably true, but if the win is pauseless automatic memory management that doesn't require twice as much memory as using a GC, then it may be worth it. I think, realistically, we'll have to accept that both tracing GC and reference counting (however smart) will always suffer from some drawbacks that manual memory management can solve. The reverse is also true.
- mzl 11y agoSure, a really smart implementation (coalescing reference count updates, concurrent de-allocations to get pauslessness, etc) could have some nice properties. However, while the amount of virtual memory needed for a tracing GC might seem large, it is not active memory. Reference counting on the other hand will significantly increase the amount of active used memory, especially if many small objects are common. As for GC vs. manual memory management, both have their uses. For most systems I would argue that GC is the way to go since it is quite efficient and is much more productive. On the other hand, I actually like writing code that has manual memory management. My current interest is learning more Rust for that kind of development.