Documentation GC (#13109)
* Update Documentation about GC, add ARC based on code observations and https://forum.nim-lang.org/t/5734#35562 * Rephrase 'Garbage Collector' on documentation, see #13331 * Peer Review Feedbacks * When the body of a documentation section is all for garbage collector details then add 'for garbage collectors' to the title to identify they may not apply for ARC * Change 'GC' for 'garbage collector'. * Move 'Memory Management Strategies' at the top, without changes * Move the info for RefC GC from 'Introduction' to 'RefC' section without changes, make 'Introduction' about Nims 'Multi-paradigm Memory Management Strategies'.
This commit is contained in:
parent
88566cc651
commit
a0ccfd16a7
1 changed files with 97 additions and 75 deletions
172
doc/gc.rst
172
doc/gc.rst
|
|
@ -1,6 +1,6 @@
|
||||||
==========================
|
=======================
|
||||||
Nim's Garbage Collector
|
Nim's Memory Management
|
||||||
==========================
|
=======================
|
||||||
|
|
||||||
:Author: Andreas Rumpf
|
:Author: Andreas Rumpf
|
||||||
:Version: |nimversion|
|
:Version: |nimversion|
|
||||||
|
|
@ -14,37 +14,78 @@ Nim's Garbage Collector
|
||||||
Introduction
|
Introduction
|
||||||
============
|
============
|
||||||
|
|
||||||
This document describes how the GC works and how to tune it for
|
This document describes how the multi-paradigm memory management strategies work.
|
||||||
(soft) `realtime systems`:idx:.
|
How to tune the garbage collectors for your needs, like (soft) `realtime systems`:idx:,
|
||||||
|
and how the memory management strategies that are not garbage collectors work.
|
||||||
The basic algorithm is *Deferred Reference Counting* with cycle detection.
|
|
||||||
References on the stack are not counted for better performance (and easier C
|
|
||||||
code generation). Cycle detection is currently done by a simple mark&sweep
|
|
||||||
GC that has to scan the full (thread local heap). ``--gc:v2`` replaces this
|
|
||||||
with an incremental mark and sweep. That it is not production ready yet,
|
|
||||||
however.
|
|
||||||
|
|
||||||
|
|
||||||
The GC is only triggered in a memory allocation operation. It is not triggered
|
Multi-paradigm Memory Management Strategies
|
||||||
by some timer and does not run in a background thread.
|
===========================================
|
||||||
|
|
||||||
To force a full collection call ``GC_fullCollect``. Note that it is generally
|
You can choose the memory management strategy to use when compiling source code,
|
||||||
better to let the GC do its work and not enforce a full collection.
|
you can pass ``--gc:`` on the compile command with the selected memory management strategy.
|
||||||
|
|
||||||
|
- ``--gc:refc`` Deferred `reference counting <https://en.wikipedia.org/wiki/Reference_counting>`_ based garbage collector
|
||||||
|
with `cycle detection <https://en.wikipedia.org/wiki/Reference_counting#Dealing_with_reference_cycles>`_
|
||||||
|
by a simple Mark&Sweep that has to scan the full heap,
|
||||||
|
is only triggered in a memory allocation operation and
|
||||||
|
it is not triggered by some timer and does not run in a background thread,
|
||||||
|
`thread local heap <https://en.wikipedia.org/wiki/Heap_(programming)>`_,
|
||||||
|
references on the stack are not counted for better performance (and easier C code generation), default.
|
||||||
|
- ``--gc:markAndSweep`` `Mark-And-Sweep <https://en.wikipedia.org/wiki/Tracing_garbage_collection#Copying_vs._mark-and-sweep_vs._mark-and-don't-sweep>`_ based garbage collector,
|
||||||
|
`thread local heap <https://en.wikipedia.org/wiki/Heap_(programming)>`_.
|
||||||
|
- ``--gc:boehm`` `Boehm <https://en.wikipedia.org/wiki/Boehm_garbage_collector>`_ based garbage collector,
|
||||||
|
`stop-the-world <https://en.wikipedia.org/wiki/Tracing_garbage_collection#Stop-the-world_vs._incremental_vs._concurrent>`_,
|
||||||
|
`shared heap <https://en.wikipedia.org/wiki/Heap_(programming)>`_.
|
||||||
|
- ``--gc:go`` Go lang like garbage collector,
|
||||||
|
`stop-the-world <https://en.wikipedia.org/wiki/Tracing_garbage_collection#Stop-the-world_vs._incremental_vs._concurrent>`_,
|
||||||
|
`shared heap <https://en.wikipedia.org/wiki/Heap_(programming)>`_.
|
||||||
|
- ``--gc:regions`` `Stack <https://en.wikipedia.org/wiki/Memory_management#Stack_allocation>`_ based garbage collector.
|
||||||
|
- ``--gc:arc`` Not a garbage collector. Plain `reference counting <https://en.wikipedia.org/wiki/Reference_counting>`_ with
|
||||||
|
`move semantic optimizations <destructors.html#move-semantics>`_,
|
||||||
|
`shared heap <https://en.wikipedia.org/wiki/Heap_(programming)>`_,
|
||||||
|
can be optimized with `sink <destructors.html#sink-parameters>`_ and `lent <destructors.html#lent-type>`_ annotations,
|
||||||
|
designed to work well with `WebAssembly <https://webassembly.org>`_, `Emscripten <https://emscripten.org>`_,
|
||||||
|
`hot code reloading <hcr.html>`_ and `address sanitizers <https://en.wikipedia.org/wiki/AddressSanitizer>`_,
|
||||||
|
basically it is like a shared heap with subgraphs with a single owner,
|
||||||
|
this is not the same as Swift and ObjectiveC lang ARC because those can not handle cycles,
|
||||||
|
can use `GOTO based Exception handling <https://nim-lang.org/araq/gotobased_exceptions.html>`_,
|
||||||
|
may become default in future releases.
|
||||||
|
- ``--gc:orc`` Not a garbage collector. Similar to ``--gc:arc`` but with improved
|
||||||
|
`cycle detection <https://en.wikipedia.org/wiki/Reference_counting#Dealing_with_reference_cycles>`_.
|
||||||
|
`Cycle detection <https://en.wikipedia.org/wiki/Reference_counting#Dealing_with_reference_cycles>`_
|
||||||
|
will not be the default, because by definition it conflicts with
|
||||||
|
`deterministic memory management <https://en.wikipedia.org/wiki/Deterministic_memory>`_.
|
||||||
|
- ``--gc:none`` No memory management strategy nor garbage collector.
|
||||||
|
You should use `Manual memory management <https://en.wikipedia.org/wiki/Manual_memory_management>`_ with it.
|
||||||
|
|
||||||
|
The same Nim code can be compiled to use any of the memory management strategies;
|
||||||
|
the Nim syntax generally will not change from one memory management strategy to another.
|
||||||
|
|
||||||
|
No garbage collector nor memory management is used for `JavaScript and NodeJS
|
||||||
|
<backends.html#backends-the-javascript-target>`_ compilation targets.
|
||||||
|
`NimScript <nims.html>`_ target uses Nim VM memory management strategy.
|
||||||
|
|
||||||
|
All memory management strategies are supported equally on Nim when possible and aplicable,
|
||||||
|
even if there is a default one, all others should also work as documented.
|
||||||
|
|
||||||
|
If you are new to Nim and just starting, the default memory management strategy is balanced to fit most common use cases.
|
||||||
|
|
||||||
|
|
||||||
Cycle collector
|
Cycle collector for garbage collectors
|
||||||
===============
|
======================================
|
||||||
|
|
||||||
The cycle collector can be en-/disabled independently from the other parts of
|
The cycle collector can be en-/disabled independently from the other parts of
|
||||||
the GC with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``.
|
the garbage collector with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``.
|
||||||
|
|
||||||
|
|
||||||
Realtime support
|
Realtime support for garbage collectors
|
||||||
================
|
=======================================
|
||||||
|
|
||||||
To enable realtime support, the symbol `useRealtimeGC`:idx: needs to be
|
To enable realtime support, the symbol `useRealtimeGC`:idx: needs to be
|
||||||
defined via ``--define:useRealtimeGC`` (you can put this into your config
|
defined via ``--define:useRealtimeGC`` (you can put this into your config
|
||||||
file as well). With this switch the GC supports the following operations:
|
file as well).
|
||||||
|
With this switch the garbage collector supports the following operations:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
proc GC_setMaxPause*(maxPauseInUs: int)
|
proc GC_setMaxPause*(maxPauseInUs: int)
|
||||||
|
|
@ -52,24 +93,26 @@ file as well). With this switch the GC supports the following operations:
|
||||||
|
|
||||||
The unit of the parameters ``maxPauseInUs`` and ``us`` is microseconds.
|
The unit of the parameters ``maxPauseInUs`` and ``us`` is microseconds.
|
||||||
|
|
||||||
These two procs are the two modus operandi of the realtime GC:
|
These two procs are the two modus operandi of the realtime garbage collector:
|
||||||
|
|
||||||
(1) GC_SetMaxPause Mode
|
(1) GC_SetMaxPause Mode
|
||||||
|
|
||||||
You can call ``GC_SetMaxPause`` at program startup and then each triggered
|
You can call ``GC_SetMaxPause`` at program startup and then each triggered
|
||||||
GC run tries to not take longer than ``maxPause`` time. However, it is
|
garbage collector run tries to not take longer than ``maxPause`` time. However, it is
|
||||||
possible (and common) that the work is nevertheless not evenly distributed
|
possible (and common) that the work is nevertheless not evenly distributed
|
||||||
as each call to ``new`` can trigger the GC and thus take ``maxPause``
|
as each call to ``new`` can trigger the garbage collector and thus take ``maxPause``
|
||||||
time.
|
time.
|
||||||
|
|
||||||
(2) GC_step Mode
|
(2) GC_step Mode
|
||||||
|
|
||||||
This allows the GC to perform some work for up to ``us`` time. This is
|
This allows the garbage collector to perform some work for up to ``us`` time.
|
||||||
useful to call in a main loop to ensure the GC can do its work. To
|
This is useful to call in a main loop to ensure the garbage collector can do its work.
|
||||||
bind all GC activity to a ``GC_step`` call, deactivate the GC with
|
To bind all garbage collector activity to a ``GC_step`` call,
|
||||||
``GC_disable`` at program startup. If ``strongAdvice`` is set to ``true``,
|
deactivate the garbage collector with ``GC_disable`` at program startup.
|
||||||
GC will be forced to perform collection cycle. Otherwise, GC may decide not
|
If ``strongAdvice`` is set to ``true``,
|
||||||
to do anything, if there is not much garbage to collect.
|
then the garbage collector will be forced to perform collection cycle.
|
||||||
|
Otherwise, the garbage collector may decide not to do anything,
|
||||||
|
if there is not much garbage to collect.
|
||||||
You may also specify the current stack size via ``stackSize`` parameter.
|
You may also specify the current stack size via ``stackSize`` parameter.
|
||||||
It can improve performance, when you know that there are no unique Nim
|
It can improve performance, when you know that there are no unique Nim
|
||||||
references below certain point on the stack. Make sure the size you specify
|
references below certain point on the stack. Make sure the size you specify
|
||||||
|
|
@ -82,11 +125,11 @@ time will be met in almost all cases on modern CPUs (with the cycle collector
|
||||||
disabled).
|
disabled).
|
||||||
|
|
||||||
|
|
||||||
Time measurement
|
Time measurement with garbage collectors
|
||||||
----------------
|
----------------------------------------
|
||||||
|
|
||||||
The GC's way of measuring time uses (see ``lib/system/timers.nim`` for the
|
The garbage collectors's way of measuring time uses
|
||||||
implementation):
|
(see ``lib/system/timers.nim`` for the implementation):
|
||||||
|
|
||||||
1) ``QueryPerformanceCounter`` and ``QueryPerformanceFrequency`` on Windows.
|
1) ``QueryPerformanceCounter`` and ``QueryPerformanceFrequency`` on Windows.
|
||||||
2) ``mach_absolute_time`` on Mac OS X.
|
2) ``mach_absolute_time`` on Mac OS X.
|
||||||
|
|
@ -95,14 +138,13 @@ implementation):
|
||||||
As such it supports a resolution of nanoseconds internally; however the API
|
As such it supports a resolution of nanoseconds internally; however the API
|
||||||
uses microseconds for convenience.
|
uses microseconds for convenience.
|
||||||
|
|
||||||
|
Define the symbol ``reportMissedDeadlines`` to make the
|
||||||
Define the symbol ``reportMissedDeadlines`` to make the GC output whenever it
|
garbage collector output whenever it missed a deadline.
|
||||||
missed a deadline. The reporting will be enhanced and supported by the API in
|
The reporting will be enhanced and supported by the API in later versions of the collector.
|
||||||
later versions of the collector.
|
|
||||||
|
|
||||||
|
|
||||||
Tweaking the GC
|
Tweaking the garbage collector
|
||||||
---------------
|
------------------------------
|
||||||
|
|
||||||
The collector checks whether there is still time left for its work after
|
The collector checks whether there is still time left for its work after
|
||||||
every ``workPackage``'th iteration. This is currently set to 100 which means
|
every ``workPackage``'th iteration. This is currently set to 100 which means
|
||||||
|
|
@ -111,25 +153,27 @@ 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.
|
||||||
|
|
||||||
|
|
||||||
Keeping track of memory
|
Keeping track of memory with garbage collectors
|
||||||
-----------------------
|
-----------------------------------------------
|
||||||
|
|
||||||
If you need to pass around memory allocated by Nim to C, you can use the
|
If you need to pass around memory allocated by Nim to C, you can use the
|
||||||
procs ``GC_ref`` and ``GC_unref`` to mark objects as referenced to avoid them
|
procs ``GC_ref`` and ``GC_unref`` to mark objects as referenced to avoid them
|
||||||
being freed by the GC. Other useful procs from `system <system.html>`_ you can
|
being freed by the garbage collector.
|
||||||
use to keep track of memory are:
|
Other useful procs from `system <system.html>`_ you can use to keep track of memory are:
|
||||||
|
|
||||||
* ``getTotalMem()`` Returns the amount of total memory managed by the GC.
|
* ``getTotalMem()`` Returns the amount of total memory managed by the garbage collector.
|
||||||
* ``getOccupiedMem()`` Bytes reserved by the GC and used by objects.
|
* ``getOccupiedMem()`` Bytes reserved by the garbage collector and used by objects.
|
||||||
* ``getFreeMem()`` Bytes reserved by the GC and not in use.
|
* ``getFreeMem()`` Bytes reserved by the garbage collector and not in use.
|
||||||
|
* ``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`` and ``--gc:go``.
|
with the exception of ``--gc:boehm`` and ``--gc:go``.
|
||||||
|
|
||||||
In addition to ``GC_ref`` and ``GC_unref`` you can avoid the GC by manually
|
In addition to ``GC_ref`` and ``GC_unref`` you can avoid the garbage collector by manually
|
||||||
allocating memory with procs like ``alloc``, ``allocShared``, or
|
allocating memory with procs like ``alloc``, ``alloc0``, ``allocShared``, ``allocShared0`` or ``allocCStringArray``.
|
||||||
``allocCStringArray``. The GC won't try to free them, you need to call their
|
The garbage collector won't try to free them, you need to call their respective *dealloc* pairs
|
||||||
respective *dealloc* pairs when you are done with them or they will leak.
|
(``dealloc``, ``deallocShared``, ``deallocCStringArray``, etc)
|
||||||
|
when you are done with them or they will leak.
|
||||||
|
|
||||||
|
|
||||||
Heap dump
|
Heap dump
|
||||||
|
|
@ -143,29 +187,7 @@ the total amount of object instances for this type as well as the total
|
||||||
amount of bytes these instances take up. This list is currently unsorted!
|
amount of bytes these instances take up. This list is currently unsorted!
|
||||||
You need to use external shell script hacking to sort it.
|
You need to use external shell script hacking to sort it.
|
||||||
|
|
||||||
The numbers count the number of objects in all GC heaps, they refer to
|
The numbers count the number of objects in all garbage collector heaps, they refer to
|
||||||
all running threads, not only to the current thread. (The current thread
|
all running threads, not only to the current thread. (The current thread
|
||||||
would be the thread that calls ``dumpNumberOfInstances``.) This might
|
would be the thread that calls ``dumpNumberOfInstances``.) This might
|
||||||
change in later versions.
|
change in later versions.
|
||||||
|
|
||||||
|
|
||||||
Garbage collector options
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
You can choose which garbage collector to use when compiling source code,
|
|
||||||
you can pass ``--gc:`` on the compile command with the choosed garbage collector.
|
|
||||||
|
|
||||||
- ``--gc:refc`` Deferred `reference counting <https://en.wikipedia.org/wiki/Reference_counting>`_ with cycle detection, `thread local heap <https://en.wikipedia.org/wiki/Heap_(programming)>`_, default.
|
|
||||||
- ``--gc:markAndSweep`` `Mark-And-Sweep <https://en.wikipedia.org/wiki/Tracing_garbage_collection#Copying_vs._mark-and-sweep_vs._mark-and-don't-sweep>`_ based garbage collector, `thread local heap <https://en.wikipedia.org/wiki/Heap_(programming)>`_.
|
|
||||||
- ``--gc:boehm`` `Boehm <https://en.wikipedia.org/wiki/Boehm_garbage_collector>`_ based garbage collector, `stop-the-world <https://en.wikipedia.org/wiki/Tracing_garbage_collection#Stop-the-world_vs._incremental_vs._concurrent>`_, `shared heap <https://en.wikipedia.org/wiki/Heap_(programming)>`_.
|
|
||||||
- ``--gc:go`` Go lang like garbage collector, `stop-the-world <https://en.wikipedia.org/wiki/Tracing_garbage_collection#Stop-the-world_vs._incremental_vs._concurrent>`_, `shared heap <https://en.wikipedia.org/wiki/Heap_(programming)>`_.
|
|
||||||
- ``--gc:regions`` `Stack <https://en.wikipedia.org/wiki/Memory_management#Stack_allocation>`_ based garbage collector.
|
|
||||||
- ``--gc:none`` No garbage collector.
|
|
||||||
|
|
||||||
The same Nim code can be compiled to use any of the garbage collectors;
|
|
||||||
the Nim syntax generally will not change from one garbage collector to another.
|
|
||||||
No garbage collector is used for `JavaScript and NodeJS
|
|
||||||
<backends.html#backends-the-javascript-target>`_ compilation targets.
|
|
||||||
`NimScript <nims.html>`_ target uses Nim VM garbage collector.
|
|
||||||
|
|
||||||
If you are new to Nim and just starting, the default garbage collector is balanced to fit most common use cases.
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue