renamed 'gc' switch to 'mm'; [backport:1.6] (#19187)
* renamed 'gc' switch to 'mm'; [backport:1.6] * better docs
This commit is contained in:
parent
c7c6b13a32
commit
a0073d2d4c
11 changed files with 157 additions and 143 deletions
|
|
@ -63,5 +63,6 @@
|
||||||
|
|
||||||
## Tool changes
|
## Tool changes
|
||||||
|
|
||||||
|
- The `gc` switch has been renamed to `mm` ("memory management") in order to reflect the
|
||||||
|
reality better. (Nim moved away from all techniques based on "tracing".)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ template deprecatedAlias(oldName, newName: string) =
|
||||||
|
|
||||||
proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo): bool =
|
proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo): bool =
|
||||||
case switch.normalize
|
case switch.normalize
|
||||||
of "gc":
|
of "gc", "mm":
|
||||||
case arg.normalize
|
case arg.normalize
|
||||||
of "boehm": result = conf.selectedGC == gcBoehm
|
of "boehm": result = conf.selectedGC == gcBoehm
|
||||||
of "refc": result = conf.selectedGC == gcRefc
|
of "refc": result = conf.selectedGC == gcRefc
|
||||||
|
|
@ -596,7 +596,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
processOnOffSwitchG(conf, {optForceFullMake}, arg, pass, info)
|
processOnOffSwitchG(conf, {optForceFullMake}, arg, pass, info)
|
||||||
of "project":
|
of "project":
|
||||||
processOnOffSwitchG(conf, {optWholeProject, optGenIndex}, arg, pass, info)
|
processOnOffSwitchG(conf, {optWholeProject, optGenIndex}, arg, pass, info)
|
||||||
of "gc":
|
of "gc", "mm":
|
||||||
if conf.backend == backendJs: return # for: bug #16033
|
if conf.backend == backendJs: return # for: bug #16033
|
||||||
expectArg(conf, switch, arg, pass, info)
|
expectArg(conf, switch, arg, pass, info)
|
||||||
if pass in {passCmd2, passPP}:
|
if pass in {passCmd2, passPP}:
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,9 @@ Advanced options:
|
||||||
--skipUserCfg:on|off do not read the user's configuration file
|
--skipUserCfg:on|off do not read the user's configuration file
|
||||||
--skipParentCfg:on|off do not read the parent dirs' configuration files
|
--skipParentCfg:on|off do not read the parent dirs' configuration files
|
||||||
--skipProjCfg:on|off do not read the project's configuration file
|
--skipProjCfg:on|off do not read the project's configuration file
|
||||||
--gc:refc|arc|orc|markAndSweep|boehm|go|none|regions
|
--mm:orc|arc|refc|markAndSweep|boehm|go|none|regions
|
||||||
select the GC to use; default is 'refc'
|
select which memory management to use; default is 'refc'
|
||||||
|
recommended is 'orc'
|
||||||
--exceptions:setjmp|cpp|goto|quirky
|
--exceptions:setjmp|cpp|goto|quirky
|
||||||
select the exception handling implementation
|
select the exception handling implementation
|
||||||
--index:on|off turn index file generation on|off
|
--index:on|off turn index file generation on|off
|
||||||
|
|
@ -163,4 +164,4 @@ Advanced options:
|
||||||
--profileVM:on|off turn compile time VM profiler on|off
|
--profileVM:on|off turn compile time VM profiler on|off
|
||||||
--sinkInference:on|off turn sink parameter inference on|off (default: on)
|
--sinkInference:on|off turn sink parameter inference on|off (default: on)
|
||||||
--panics:on|off turn panics into process terminations (default: off)
|
--panics:on|off turn panics into process terminations (default: off)
|
||||||
--deepcopy:on|off enable 'system.deepCopy' for ``--gc:arc|orc``
|
--deepcopy:on|off enable 'system.deepCopy' for ``--mm:arc|orc``
|
||||||
|
|
|
||||||
|
|
@ -387,14 +387,8 @@ A similar thing happens with C code invoking Nim code which returns a
|
||||||
proc gimme(): cstring {.exportc.} =
|
proc gimme(): cstring {.exportc.} =
|
||||||
result = "Hey there C code! " & $rand(100)
|
result = "Hey there C code! " & $rand(100)
|
||||||
|
|
||||||
Since Nim's garbage collector is not aware of the C code, once the
|
Since Nim's reference counting mechanism is not aware of the C code, once the
|
||||||
`gimme` proc has finished it can reclaim the memory of the `cstring`.
|
`gimme` proc has finished it can reclaim the memory of the `cstring`.
|
||||||
However, from a practical standpoint, the C code invoking the `gimme`
|
|
||||||
function directly will be able to use it since Nim's garbage collector has
|
|
||||||
not had a chance to run *yet*. This gives you enough time to make a copy for
|
|
||||||
the C side of the program, as calling any further Nim procs *might* trigger
|
|
||||||
garbage collection making the previously returned string garbage. Or maybe you
|
|
||||||
are `yourself triggering the collection <gc.html>`_.
|
|
||||||
|
|
||||||
|
|
||||||
Custom data types
|
Custom data types
|
||||||
|
|
@ -414,31 +408,3 @@ you can clean it up. And of course, once cleaned you should avoid accessing it
|
||||||
from Nim (or C for that matter). Typically C data structures have their own
|
from Nim (or C for that matter). Typically C data structures have their own
|
||||||
`malloc_structure`:c: and `free_structure`:c: specific functions, so wrapping
|
`malloc_structure`:c: and `free_structure`:c: specific functions, so wrapping
|
||||||
these for the Nim side should be enough.
|
these for the Nim side should be enough.
|
||||||
|
|
||||||
|
|
||||||
Thread coordination
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
When the `NimMain()` function is called Nim initializes the garbage
|
|
||||||
collector to the current thread, which is usually the main thread of your
|
|
||||||
application. If your C code later spawns a different thread and calls Nim
|
|
||||||
code, the garbage collector will fail to work properly and you will crash.
|
|
||||||
|
|
||||||
As long as you don't use the threadvar emulation Nim uses native thread
|
|
||||||
variables, of which you get a fresh version whenever you create a thread. You
|
|
||||||
can then attach a GC to this thread via
|
|
||||||
|
|
||||||
.. code-block:: nim
|
|
||||||
|
|
||||||
system.setupForeignThreadGc()
|
|
||||||
|
|
||||||
It is **not** safe to disable the garbage collector and enable it after the
|
|
||||||
call from your background thread even if the code you are calling is short
|
|
||||||
lived.
|
|
||||||
|
|
||||||
Before the thread exits, you should tear down the thread's GC to prevent memory
|
|
||||||
leaks by calling
|
|
||||||
|
|
||||||
.. code-block:: nim
|
|
||||||
|
|
||||||
system.tearDownForeignThreadGc()
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ written as:
|
||||||
dealloc(x.data)
|
dealloc(x.data)
|
||||||
|
|
||||||
proc `=trace`[T](x: var myseq[T]; env: pointer) =
|
proc `=trace`[T](x: var myseq[T]; env: pointer) =
|
||||||
# `=trace` allows the cycle collector `--gc:orc`
|
# `=trace` allows the cycle collector `--mm:orc`
|
||||||
# to understand how to trace the object graph.
|
# to understand how to trace the object graph.
|
||||||
if x.data != nil:
|
if x.data != nil:
|
||||||
for i in 0..<x.len: `=trace`(x.data[i], env)
|
for i in 0..<x.len: `=trace`(x.data[i], env)
|
||||||
|
|
@ -208,7 +208,7 @@ by the compiler. Notice that there is no `=` before the `{.error.}` pragma.
|
||||||
`=trace` hook
|
`=trace` hook
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
A custom **container** type can support Nim's cycle collector `--gc:orc` via
|
A custom **container** type can support Nim's cycle collector `--mm:orc` via
|
||||||
the `=trace` hook. If the container does not implement `=trace`, cyclic data
|
the `=trace` hook. If the container does not implement `=trace`, cyclic data
|
||||||
structures which are constructed with the help of the container might leak
|
structures which are constructed with the help of the container might leak
|
||||||
memory or resources, but memory safety is not compromised.
|
memory or resources, but memory safety is not compromised.
|
||||||
|
|
@ -224,7 +224,7 @@ to calls of the built-in `=trace` operation.
|
||||||
|
|
||||||
Usually there will only be a need for a custom `=trace` when a custom `=destroy` that deallocates
|
Usually there will only be a need for a custom `=trace` when a custom `=destroy` that deallocates
|
||||||
manually allocated resources is also used, and then only when there is a chance of cyclic
|
manually allocated resources is also used, and then only when there is a chance of cyclic
|
||||||
references from items within the manually allocated resources when it is desired that `--gc:orc`
|
references from items within the manually allocated resources when it is desired that `--mm:orc`
|
||||||
is able to break and collect these cyclic referenced resources. Currently however, there is a
|
is able to break and collect these cyclic referenced resources. Currently however, there is a
|
||||||
mutual use problem in that whichever of `=destroy`/`=trace` is used first will automatically
|
mutual use problem in that whichever of `=destroy`/`=trace` is used first will automatically
|
||||||
create a version of the other which will then conflict with the creation of the second of the
|
create a version of the other which will then conflict with the creation of the second of the
|
||||||
|
|
@ -256,7 +256,7 @@ The general pattern in using `=destroy` with `=trace` looks like:
|
||||||
|
|
||||||
# following may be other custom "hooks" as required...
|
# following may be other custom "hooks" as required...
|
||||||
|
|
||||||
**Note**: The `=trace` hooks (which are only used by `--gc:orc`) are currently more experimental and less refined
|
**Note**: The `=trace` hooks (which are only used by `--mm:orc`) are currently more experimental and less refined
|
||||||
than the other hooks.
|
than the other hooks.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -558,10 +558,10 @@ for expressions of type `lent T` or of type `var T`.
|
||||||
The cursor pragma
|
The cursor pragma
|
||||||
=================
|
=================
|
||||||
|
|
||||||
Under the `--gc:arc|orc`:option: modes Nim's `ref` type is implemented
|
Under the `--mm:arc|orc`:option: modes Nim's `ref` type is implemented
|
||||||
via the same runtime "hooks" and thus via reference counting.
|
via the same runtime "hooks" and thus via reference counting.
|
||||||
This means that cyclic structures cannot be freed
|
This means that cyclic structures cannot be freed
|
||||||
immediately (`--gc:orc`:option: ships with a cycle collector).
|
immediately (`--mm:orc`:option: ships with a cycle collector).
|
||||||
With the `cursor` pragma one can break up cycles declaratively:
|
With the `cursor` pragma one can break up cycles declaratively:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ The documentation consists of several documents:
|
||||||
- | `Tools documentation <tools.html>`_
|
- | `Tools documentation <tools.html>`_
|
||||||
| Description of some tools that come with the standard distribution.
|
| Description of some tools that come with the standard distribution.
|
||||||
|
|
||||||
- | `GC <gc.html>`_
|
- | `Memory management <mm.html>`_
|
||||||
| Additional documentation about Nim's multi-paradigm memory management strategies
|
| Additional documentation about Nim's memory management strategies
|
||||||
| and how to operate them in a realtime setting.
|
| and how to operate them in a realtime setting.
|
||||||
|
|
||||||
- | `Source code filters <filters.html>`_
|
- | `Source code filters <filters.html>`_
|
||||||
|
|
|
||||||
95
doc/mm.rst
Normal file
95
doc/mm.rst
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
=======================
|
||||||
|
Nim's Memory Management
|
||||||
|
=======================
|
||||||
|
|
||||||
|
.. default-role:: code
|
||||||
|
.. include:: rstcommon.rst
|
||||||
|
|
||||||
|
:Author: Andreas Rumpf
|
||||||
|
:Version: |nimversion|
|
||||||
|
|
||||||
|
..
|
||||||
|
|
||||||
|
|
||||||
|
"The road to hell is paved with good intentions."
|
||||||
|
|
||||||
|
|
||||||
|
Multi-paradigm Memory Management Strategies
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
.. default-role:: option
|
||||||
|
|
||||||
|
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`.**
|
||||||
|
|
||||||
|
|
||||||
|
ARC/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 <destructors.html#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`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Other MM modes
|
||||||
|
--------------
|
||||||
|
|
||||||
|
.. 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 <refc.html>`_ 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`
|
||||||
|
================== ======== ================= ============== ===================
|
||||||
|
|
||||||
|
.. default-role:: code
|
||||||
|
.. include:: rstcommon.rst
|
||||||
|
|
||||||
|
JavaScript's garbage collector is used for the `JavaScript and NodeJS
|
||||||
|
<backends.html#backends-the-javascript-target>`_ compilation targets.
|
||||||
|
The `NimScript <nims.html>`_ target uses the memory management strategy built into
|
||||||
|
the Nim compiler.
|
||||||
18
doc/nimc.rst
18
doc/nimc.rst
|
|
@ -408,13 +408,13 @@ to your usual `nim c`:cmd: or `nim cpp`:cmd: command and set the `passC`:option:
|
||||||
and `passL`:option: command line switches to something like:
|
and `passL`:option: command line switches to something like:
|
||||||
|
|
||||||
.. code-block:: cmd
|
.. code-block:: cmd
|
||||||
nim c ... --d:nimAllocPagesViaMalloc --gc:orc --passC="-I$DEVKITPRO/libnx/include" ...
|
nim c ... --d:nimAllocPagesViaMalloc --mm:orc --passC="-I$DEVKITPRO/libnx/include" ...
|
||||||
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
|
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
|
||||||
|
|
||||||
or setup a ``nim.cfg`` file like so::
|
or setup a ``nim.cfg`` file like so::
|
||||||
|
|
||||||
#nim.cfg
|
#nim.cfg
|
||||||
--gc:orc
|
--mm:orc
|
||||||
--d:nimAllocPagesViaMalloc
|
--d:nimAllocPagesViaMalloc
|
||||||
--passC="-I$DEVKITPRO/libnx/include"
|
--passC="-I$DEVKITPRO/libnx/include"
|
||||||
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
|
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
|
||||||
|
|
@ -485,10 +485,10 @@ Define Effect
|
||||||
`useMalloc` Makes Nim use C's `malloc`:idx: instead of Nim's
|
`useMalloc` Makes Nim use C's `malloc`:idx: instead of Nim's
|
||||||
own memory manager, albeit prefixing each allocation with
|
own memory manager, albeit prefixing each allocation with
|
||||||
its size to support clearing memory on reallocation.
|
its size to support clearing memory on reallocation.
|
||||||
This only works with `--gc:none`:option:,
|
This only works with `--mm:none`:option:,
|
||||||
`--gc:arc`:option: and `--gc:orc`:option:.
|
`--mm:arc`:option: and `--mm:orc`:option:.
|
||||||
`useRealtimeGC` Enables support of Nim's GC for *soft* realtime
|
`useRealtimeGC` Enables support of Nim's GC for *soft* realtime
|
||||||
systems. See the documentation of the `gc <gc.html>`_
|
systems. See the documentation of the `mm <mm.html>`_
|
||||||
for further information.
|
for further information.
|
||||||
`logGC` Enable GC logging to stdout.
|
`logGC` Enable GC logging to stdout.
|
||||||
`nodejs` The JS target is actually ``node.js``.
|
`nodejs` The JS target is actually ``node.js``.
|
||||||
|
|
@ -614,9 +614,9 @@ A good start is to use the `any` operating target together with the
|
||||||
|
|
||||||
.. code:: cmd
|
.. code:: cmd
|
||||||
|
|
||||||
nim c --os:any --gc:arc -d:useMalloc [...] x.nim
|
nim c --os:any --mm:arc -d:useMalloc [...] x.nim
|
||||||
|
|
||||||
- `--gc:arc`:option: will enable the reference counting memory management instead
|
- `--mm:arc`:option: will enable the reference counting memory management instead
|
||||||
of the default garbage collector. This enables Nim to use heap memory which
|
of the default garbage collector. This enables Nim to use heap memory which
|
||||||
is required for strings and seqs, for example.
|
is required for strings and seqs, for example.
|
||||||
|
|
||||||
|
|
@ -654,7 +654,7 @@ devices. This allocator gets blocks/pages of memory via a currently undocumented
|
||||||
`osalloc` API which usually uses POSIX's `mmap` call. On many environments `mmap`
|
`osalloc` API which usually uses POSIX's `mmap` call. On many environments `mmap`
|
||||||
is not available but C's `malloc` is. You can use the `nimAllocPagesViaMalloc`
|
is not available but C's `malloc` is. You can use the `nimAllocPagesViaMalloc`
|
||||||
define to use `malloc` instead of `mmap`. `nimAllocPagesViaMalloc` is currently
|
define to use `malloc` instead of `mmap`. `nimAllocPagesViaMalloc` is currently
|
||||||
only supported with `--gc:arc` or `--gc:orc`. (Since version 1.6)
|
only supported with `--mm:arc` or `--mm:orc`. (Since version 1.6)
|
||||||
|
|
||||||
nimPage256 / nimPage512 / nimPage1k
|
nimPage256 / nimPage512 / nimPage1k
|
||||||
===================================
|
===================================
|
||||||
|
|
@ -693,7 +693,7 @@ Currently only Zephyr and FreeRTOS support these configurations.
|
||||||
Nim for realtime systems
|
Nim for realtime systems
|
||||||
========================
|
========================
|
||||||
|
|
||||||
See the documentation of Nim's soft realtime `GC <gc.html>`_ for further
|
See the `--mm:arc` or `--mm:orc` memory management settings in `MM <mm.html>`_ for further
|
||||||
information.
|
information.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,81 +1,3 @@
|
||||||
=======================
|
|
||||||
Nim's Memory Management
|
|
||||||
=======================
|
|
||||||
|
|
||||||
.. default-role:: code
|
|
||||||
.. include:: rstcommon.rst
|
|
||||||
|
|
||||||
:Author: Andreas Rumpf
|
|
||||||
:Version: |nimversion|
|
|
||||||
|
|
||||||
..
|
|
||||||
|
|
||||||
|
|
||||||
"The road to hell is paved with good intentions."
|
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
============
|
|
||||||
|
|
||||||
A memory-management algorithm optimal for every use-case cannot exist.
|
|
||||||
Nim provides multiple paradigms for needs ranging from large multi-threaded
|
|
||||||
applications, to games, hard-realtime systems and small microcontrollers.
|
|
||||||
|
|
||||||
This document describes how the management strategies work;
|
|
||||||
How to tune the garbage collectors for your needs, like (soft) `realtime systems`:idx:,
|
|
||||||
and how the memory management strategies other than garbage collectors work.
|
|
||||||
|
|
||||||
.. note:: the default GC is incremental, thread-local and not "stop-the-world"
|
|
||||||
|
|
||||||
Multi-paradigm Memory Management Strategies
|
|
||||||
===========================================
|
|
||||||
|
|
||||||
.. default-role:: option
|
|
||||||
|
|
||||||
To choose the memory management strategy use the `--gc:` switch.
|
|
||||||
|
|
||||||
--gc:refc This is the default GC. 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.
|
|
||||||
--gc:markAndSweep Simple Mark-And-Sweep based garbage collector.
|
|
||||||
Heaps are thread-local.
|
|
||||||
--gc:boehm Boehm based garbage collector, it offers a shared heap.
|
|
||||||
--gc:go Go's garbage collector, useful for interoperability with Go.
|
|
||||||
Offers a shared heap.
|
|
||||||
--gc:arc Plain reference counting with
|
|
||||||
`move semantic optimizations <destructors.html#move-semantics>`_, offers a shared heap.
|
|
||||||
It offers deterministic performance for `hard realtime`:idx: systems. Reference cycles
|
|
||||||
cause memory leaks, beware.
|
|
||||||
|
|
||||||
--gc:orc Same as `--gc:arc` but adds a cycle collector based on "trial deletion".
|
|
||||||
Unfortunately, that makes its performance profile hard to reason about so it is less
|
|
||||||
useful for hard real-time systems.
|
|
||||||
|
|
||||||
--gc:none No memory management strategy nor a garbage collector. Allocated memory is
|
|
||||||
simply never freed. You should use `--gc:arc` instead.
|
|
||||||
|
|
||||||
|
|
||||||
================== ======== ================= ============== ===================
|
|
||||||
Memory Management Heap Reference Cycles Stop-The-World Command line switch
|
|
||||||
================== ======== ================= ============== ===================
|
|
||||||
RefC Local Cycle Collector No `--gc:refc`
|
|
||||||
Mark & Sweep Local Cycle Collector No `--gc:markAndSweep`
|
|
||||||
ARC Shared Leak No `--gc:arc`
|
|
||||||
ORC Shared Cycle Collector No `--gc:orc`
|
|
||||||
Boehm Shared Cycle Collector Yes `--gc:boehm`
|
|
||||||
Go Shared Cycle Collector Yes `--gc:go`
|
|
||||||
None Manual Manual Manual `--gc:none`
|
|
||||||
================== ======== ================= ============== ===================
|
|
||||||
|
|
||||||
.. default-role:: code
|
|
||||||
.. include:: rstcommon.rst
|
|
||||||
|
|
||||||
JavaScript's garbage collector is used for the `JavaScript and NodeJS
|
|
||||||
<backends.html#backends-the-javascript-target>`_ compilation targets.
|
|
||||||
The `NimScript <nims.html>`_ target uses the memory management strategy built into
|
|
||||||
the Nim compiler.
|
|
||||||
|
|
||||||
|
|
||||||
Tweaking the refc GC
|
Tweaking the refc GC
|
||||||
====================
|
====================
|
||||||
|
|
||||||
|
|
@ -164,6 +86,35 @@ that up to 100 objects are traversed and freed before it checks again. Thus
|
||||||
highly specialized environments or for older hardware.
|
highly specialized environments or for older hardware.
|
||||||
|
|
||||||
|
|
||||||
|
Thread coordination
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
When the `NimMain()` function is called Nim initializes the garbage
|
||||||
|
collector to the current thread, which is usually the main thread of your
|
||||||
|
application. If your C code later spawns a different thread and calls Nim
|
||||||
|
code, the garbage collector will fail to work properly and you will crash.
|
||||||
|
|
||||||
|
As long as you don't use the threadvar emulation Nim uses native thread
|
||||||
|
variables, of which you get a fresh version whenever you create a thread. You
|
||||||
|
can then attach a GC to this thread via
|
||||||
|
|
||||||
|
.. code-block:: nim
|
||||||
|
|
||||||
|
system.setupForeignThreadGc()
|
||||||
|
|
||||||
|
It is **not** safe to disable the garbage collector and enable it after the
|
||||||
|
call from your background thread even if the code you are calling is short
|
||||||
|
lived.
|
||||||
|
|
||||||
|
Before the thread exits, you should tear down the thread's GC to prevent memory
|
||||||
|
leaks by calling
|
||||||
|
|
||||||
|
.. code-block:: nim
|
||||||
|
|
||||||
|
system.tearDownForeignThreadGc()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Keeping track of memory
|
Keeping track of memory
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
|
@ -178,7 +129,7 @@ Other useful procs from `system <system.html>`_ you can use to keep track of mem
|
||||||
* `GC_getStatistics()` Garbage collector statistics as a human-readable string.
|
* `GC_getStatistics()` Garbage collector statistics as a human-readable string.
|
||||||
|
|
||||||
These numbers are usually only for the running thread, not for the whole heap,
|
These numbers are usually only for the running thread, not for the whole heap,
|
||||||
with the exception of `--gc:boehm`:option: and `--gc:go`:option:.
|
with the exception of `--mm:boehm`:option: and `--mm:go`:option:.
|
||||||
|
|
||||||
In addition to `GC_ref` and `GC_unref` you can avoid the garbage collector by manually
|
In addition to `GC_ref` and `GC_unref` you can avoid the garbage collector by manually
|
||||||
allocating memory with procs like `alloc`, `alloc0`, `allocShared`, `allocShared0` or `allocCStringArray`.
|
allocating memory with procs like `alloc`, `alloc0`, `allocShared`, `allocShared0` or `allocCStringArray`.
|
||||||
2
koch.nim
2
koch.nim
|
|
@ -604,7 +604,7 @@ proc runCI(cmd: string) =
|
||||||
|
|
||||||
when not defined(bsd):
|
when not defined(bsd):
|
||||||
# the BSDs are overwhelmed already, so only run this test on the other machines:
|
# the BSDs are overwhelmed already, so only run this test on the other machines:
|
||||||
kochExecFold("Boot Nim ORC", "boot -d:release --gc:orc --lib:lib")
|
kochExecFold("Boot Nim ORC", "boot -d:release --mm:orc --lib:lib")
|
||||||
|
|
||||||
proc testUnixInstall(cmdLineRest: string) =
|
proc testUnixInstall(cmdLineRest: string) =
|
||||||
csource("-d:danger" & cmdLineRest)
|
csource("-d:danger" & cmdLineRest)
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ tut2.rst
|
||||||
tut3.rst
|
tut3.rst
|
||||||
nimc.rst
|
nimc.rst
|
||||||
niminst.rst
|
niminst.rst
|
||||||
gc.rst
|
mm.rst
|
||||||
""".splitWhitespace().mapIt("doc" / it)
|
""".splitWhitespace().mapIt("doc" / it)
|
||||||
|
|
||||||
doc0 = """
|
doc0 = """
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue