[swift-evolution] What about garbage collection?

Jonathan Tang jonathan.d.tang at gmail.com
Mon Feb 8 14:34:20 CST 2016


On Mon, Feb 8, 2016 at 12:11 PM, Joe Groff via swift-evolution <
swift-evolution at swift.org> wrote:

>
> On Feb 8, 2016, at 11:56 AM, FĂ©lix Cloutier via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Has there been a garbage collection thread so far? I understand that
> reference counting vs. garbage collection can be a heated debate, but it
> might be relevant to have it.
>
> It seems to me that the two principal upsides of reference counting are
> that destruction is (essentially) deterministic and performance is more
> easily predicted. However, it comes with many downsides:
>
>
>    - object references are expensive to update
>    - object references cannot be atomically updated
>    - heap fragmentation
>    - the closure capture syntax uses up an unreasonable amount of
>    mindshare just because of [weak self]
>
>
> Since Swift doesn't expose memory management operations outside of
> `autoreleasepool`, it seems to me that you could just drop in a garbage
> collector instead of reference counting and it would work (for most
> purposes).
>
>
> While true in theory, code that relies on destructors to clean up
> unmanaged resources does not port cleanly to GC as-is in practice. GC of
> course has its own drawbacks. Heap scanning is expensive, thrashing cache
> and burning battery. GCs also require higher memory ceiling proportional to
> the amount of heap actively being used, and GCs suitable for interactive
> use tend to increase responsiveness at the cost of higher memory use, which
> has its own second-order energy costs—devices need more RAM, and spend more
> time swapping or killing, and thus need bigger batteries to refresh all
> that RAM. ARC interoperates better with unmanaged resources, both
> non-memory resources like sockets and files and also C-level memory
> resources. The ARC optimizer and Swift's calling convention also optimize
> toward reclaiming resources closer to their last use, keeping resource
> usage low.
>
>
>
I would imagine that the biggest consideration is compatibility with
existing class libraries.  It's notoriously difficult to integrate
libraries with different memory management systems together, whether it be
GC + refcounting (Erlang binaries, Java NIO), GC + malloc (JNI, V8
embedding), or refcounting + malloc (Python, ARC/C libraries).  The
ownership conventions have to become part of every function & data type
that's exposed across the boundary, and oftentimes you need to copy the
whole memory block from one heap to another.  Refcounting seems to
integrate with manual memory management a bit more easily than GC does, and
of course many existing class libraries already use ARC.

Also, anyone interested in debating GC vs. refcounting should read this
paper, which argues that they are in fact duals and most production systems
(generational collectors, train algorithm, cycle detection in refcounts)
are hybrids of the two:

http://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon04Unified.pdf
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160208/e3c0846b/attachment.html>


More information about the swift-evolution mailing list