# ARC

So ... this feature has been in development for quite some time now, Nim is 
getting the "one GC to rule them all". However calling it a GC doesn't do it 
justice, it's plain old reference counting with optimizations thanks to move 
semantics. It has numerous advantages over the other more classical GC 
algorithms that Nim 1.0 ships with:

  * Independent of the heap size. Works well with tiny and enormous heaps.
  * Independent of the stack size, large arrays on the stack do not cause 
slowdowns.
  * Offers a shared heap. Enabled via `--threads:on`.
  * Works with valgrind and clang's address sanitizers, compile with `-gc:arc 
-d:useMalloc` (and maybe with `--debuginfo`) for enabling this feature.
  * No more `setupForeignGC` requirements.
  * Should work better with hot code reloading and DLLs.
  * Should work better with fibers, coroutines or whatever C++ ends up 
providing. ;-)
  * Should work well with webassembly and Emscripten.



However, this is still **beta quality** software: Nim's async does not work 
with it yet, there are other known and unknown bugs and we haven't optimized it 
as much as we will.

## Supported language features

  * Threads and channels
  * closures
  * refs
  * strings
  * seqs
  * closure iterators
  * case objects
  * the collections in the stdlib
  * strutils, os, osproc, re, json



## To do

  * Optimize the stdlib with `sink` and `lent` annotations.
  * Optimize init+sink pairs into plain copyMem calls.
  * Optimize away wasMoved+destructor pairs.
  * Port async to --gc:arc.
  * Exceptions are known to be buggy, will probably be replaced by a mechanism 
based on the "quirky exceptions" ideas.
  * Bugfixing. Omg, still so many bugs left...



## Features that won't work for the foreseeable future

  * the old runtime type information (RTTI, `typeinfo.nim`) and modules that 
rely on it such as `marshal.nim`
  * `system.new` that takes a finalizer, instead use destructors



## Arguments and comebacks

Q: My program runs slower than before.

A: The old GC was tuned for years and can be hard to beat performance wise. ARC 
shines because it uses less memory and introduces deterministic behaviour. 
Having said that, I usually get it to win over Nim's other GCs (both in time 
and space) by inserting strategic `sink` and `lent` annotations.

Q: I cannot be bothered with cycles.

A: We have a cycle collector too but it's not even in alpha state yet, you can 
tinker with it via `--gc:orc` (the "o" indicating it can deal with cycles...) 
Having said that, cycle detection will not be the default as it in conflict 
with ARC's strive for deterministic memory management.

Q: Atomic reference counting is known to be slow

A: We **do not do atomic** reference counting, we have a shared heap where you 
move subgraphs completely to a different thread. A graph is always owned by a 
single thread, there is no need to make the reference counting atomic. We have 
mechanisms in development to ensure this at runtime or at compile-time, 
inspired by the Pony programming language.

Q: Ok, I'm sold! How to get --gc:arc? A: Follow these instructions:
    
    
    git clone https://github.com/nim-lang/nim.git
    cd nim
    
    sh ./build_all.sh # (Linux, Mac)
    build_all.bat # (Windows)
    
    
    Run

Merry Christmas!

Reply via email to