# 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!