Author: | Andreas Rumpf |
---|---|
Version: | |nimversion| |
"The road to hell is paved with good intentions."
Nim offers multiple different memory management strategies.
To choose the memory management strategy use the --mm:
switch.
The recommended switch for newly written Nim code is `--mm:orc`.
--mm:orc
is a memory management mode primarily based on reference counting. Cycles
in the object graph are handled by a "cycle collector" which is based on "trial deletion".
Since algorithms based on "tracing" are not used, the runtime behavior is oblivious to
the involved heap sizes.
The reference counting operations (= "RC ops") do not use atomic instructions and do not have to -- instead entire subgraphs are moved between threads. The Nim compiler also aggressively optimizes away RC ops and exploits move semantics.
Nim performs a fair share of optimizations for ARC/ORC; you can inspect what it did
to your time critical function via --expandArc:functionName
.
--mm:arc
uses the same mechanism as --mm:orc
, but it leaves out the cycle collector.
Both ARC and ORC offer deterministic performance for `hard realtime`:idx: systems, but
ARC can be easier to reason about for people coming from Ada/C++/C -- roughly speaking
the memory for a variable is freed when it goes "out of scope".
We generally advise you to use the acyclic
annotation in order to optimize away the
cycle collector's overhead
but --mm:orc
also produces more machine code than --mm:arc
, so if you're on a target
where code size matters and you know that your code does not produce cycles, you can
use --mm:arc
. Notice that the default `async`:idx: implementation produces cycles
and leaks memory with --mm:arc
, in other words, for async
you need to use --mm:orc
.
Note
The default refc
GC is incremental, thread-local and not "stop-the-world".
- --mm:refc This is the default memory management strategy. It's a
- deferred reference counting based garbage collector with a simple Mark&Sweep backup GC in order to collect cycles. Heaps are thread-local. This document contains further information.
- --mm:markAndSweep Simple Mark-And-Sweep based garbage collector.
- Heaps are thread-local.
--mm:boehm Boehm based garbage collector, it offers a shared heap. --mm:go Go's garbage collector, useful for interoperability with Go.
Offers a shared heap.
- --mm:none No memory management strategy nor a garbage collector. Allocated memory is
- simply never freed. You should use
--mm:arc
instead.
Here is a comparison of the different memory management modes:
Memory Management | Heap | Reference Cycles | Stop-The-World | Command line switch |
---|---|---|---|---|
ORC | Shared | Cycle Collector | No | --mm:orc |
ARC | Shared | Leak | No | --mm:arc |
RefC | Local | Cycle Collector | No | --mm:refc |
Mark & Sweep | Local | Cycle Collector | No | --mm:markAndSweep |
Boehm | Shared | Cycle Collector | Yes | --mm:boehm |
Go | Shared | Cycle Collector | Yes | --mm:go |
None | Manual | Manual | Manual | --mm:none |
JavaScript's garbage collector is used for the JavaScript and NodeJS compilation targets. The NimScript target uses the memory management strategy built into the Nim compiler.