gc.rst 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. =======================
  2. Nim's Memory Management
  3. =======================
  4. .. default-role:: code
  5. .. include:: rstcommon.rst
  6. :Author: Andreas Rumpf
  7. :Version: |nimversion|
  8. ..
  9. "The road to hell is paved with good intentions."
  10. Introduction
  11. ============
  12. A memory-management algorithm optimal for every use-case cannot exist.
  13. Nim provides multiple paradigms for needs ranging from large multi-threaded
  14. applications, to games, hard-realtime systems and small microcontrollers.
  15. This document describes how the management strategies work;
  16. How to tune the garbage collectors for your needs, like (soft) `realtime systems`:idx:,
  17. and how the memory management strategies other than garbage collectors work.
  18. .. note:: the default GC is incremental, thread-local and not "stop-the-world"
  19. Multi-paradigm Memory Management Strategies
  20. ===========================================
  21. .. default-role:: option
  22. To choose the memory management strategy use the `--gc:` switch.
  23. --gc:refc This is the default GC. It's a
  24. deferred reference counting based garbage collector
  25. with a simple Mark&Sweep backup GC in order to collect cycles. Heaps are thread-local.
  26. --gc:markAndSweep Simple Mark-And-Sweep based garbage collector.
  27. Heaps are thread-local.
  28. --gc:boehm Boehm based garbage collector, it offers a shared heap.
  29. --gc:go Go's garbage collector, useful for interoperability with Go.
  30. Offers a shared heap.
  31. --gc:arc Plain reference counting with
  32. `move semantic optimizations <destructors.html#move-semantics>`_, offers a shared heap.
  33. It offers deterministic performance for `hard realtime`:idx: systems. Reference cycles
  34. cause memory leaks, beware.
  35. --gc:orc Same as `--gc:arc` but adds a cycle collector based on "trial deletion".
  36. Unfortunately, that makes its performance profile hard to reason about so it is less
  37. useful for hard real-time systems.
  38. --gc:none No memory management strategy nor a garbage collector. Allocated memory is
  39. simply never freed. You should use `--gc:arc` instead.
  40. ================== ======== ================= ============== ===================
  41. Memory Management Heap Reference Cycles Stop-The-World Command line switch
  42. ================== ======== ================= ============== ===================
  43. RefC Local Cycle Collector No `--gc:refc`
  44. Mark & Sweep Local Cycle Collector No `--gc:markAndSweep`
  45. ARC Shared Leak No `--gc:arc`
  46. ORC Shared Cycle Collector No `--gc:orc`
  47. Boehm Shared Cycle Collector Yes `--gc:boehm`
  48. Go Shared Cycle Collector Yes `--gc:go`
  49. None Manual Manual Manual `--gc:none`
  50. ================== ======== ================= ============== ===================
  51. .. default-role:: code
  52. .. include:: rstcommon.rst
  53. JavaScript's garbage collector is used for the `JavaScript and NodeJS
  54. <backends.html#backends-the-javascript-target>`_ compilation targets.
  55. The `NimScript <nims.html>`_ target uses the memory management strategy built into
  56. the Nim compiler.
  57. Tweaking the refc GC
  58. ====================
  59. Cycle collector
  60. ---------------
  61. The cycle collector can be en-/disabled independently from the other parts of
  62. the garbage collector with `GC_enableMarkAndSweep` and `GC_disableMarkAndSweep`.
  63. Soft real-time support
  64. ----------------------
  65. To enable real-time support, the symbol `useRealtimeGC`:idx: needs to be
  66. defined via `--define:useRealtimeGC`:option: (you can put this into your config
  67. file as well).
  68. With this switch the garbage collector supports the following operations:
  69. .. code-block:: nim
  70. proc GC_setMaxPause*(maxPauseInUs: int)
  71. proc GC_step*(us: int, strongAdvice = false, stackSize = -1)
  72. The unit of the parameters `maxPauseInUs` and `us` is microseconds.
  73. These two procs are the two modus operandi of the real-time garbage collector:
  74. (1) GC_SetMaxPause Mode
  75. You can call `GC_SetMaxPause` at program startup and then each triggered
  76. garbage collector run tries to not take longer than `maxPause` time. However, it is
  77. possible (and common) that the work is nevertheless not evenly distributed
  78. as each call to `new` can trigger the garbage collector and thus take `maxPause`
  79. time.
  80. (2) GC_step Mode
  81. This allows the garbage collector to perform some work for up to `us` time.
  82. This is useful to call in the main loop to ensure the garbage collector can do its work.
  83. To bind all garbage collector activity to a `GC_step` call,
  84. deactivate the garbage collector with `GC_disable` at program startup.
  85. If `strongAdvice` is set to `true`,
  86. then the garbage collector will be forced to perform the collection cycle.
  87. Otherwise, the garbage collector may decide not to do anything,
  88. if there is not much garbage to collect.
  89. You may also specify the current stack size via `stackSize` parameter.
  90. It can improve performance when you know that there are no unique Nim references
  91. below a certain point on the stack. Make sure the size you specify is greater
  92. than the potential worst-case size.
  93. It can improve performance when you know that there are no unique Nim
  94. references below a certain point on the stack. Make sure the size you specify
  95. is greater than the potential worst-case size.
  96. These procs provide a "best effort" real-time guarantee; in particular the
  97. cycle collector is not aware of deadlines. Deactivate it to get more
  98. predictable real-time behaviour. Tests show that a 1ms max pause
  99. time will be met in almost all cases on modern CPUs (with the cycle collector
  100. disabled).
  101. Time measurement with garbage collectors
  102. ----------------------------------------
  103. The garbage collectors' way of measuring time uses
  104. (see ``lib/system/timers.nim`` for the implementation):
  105. 1) `QueryPerformanceCounter` and `QueryPerformanceFrequency` on Windows.
  106. 2) `mach_absolute_time` on Mac OS X.
  107. 3) `gettimeofday` on Posix systems.
  108. As such it supports a resolution of nanoseconds internally; however, the API
  109. uses microseconds for convenience.
  110. Define the symbol `reportMissedDeadlines` to make the
  111. garbage collector output whenever it missed a deadline.
  112. The reporting will be enhanced and supported by the API in later versions of the collector.
  113. Tweaking the garbage collector
  114. ------------------------------
  115. The collector checks whether there is still time left for its work after
  116. every `workPackage`'th iteration. This is currently set to 100 which means
  117. that up to 100 objects are traversed and freed before it checks again. Thus
  118. `workPackage` affects the timing granularity and may need to be tweaked in
  119. highly specialized environments or for older hardware.
  120. Keeping track of memory
  121. =======================
  122. If you need to pass around memory allocated by Nim to C, you can use the
  123. procs `GC_ref` and `GC_unref` to mark objects as referenced to avoid them
  124. being freed by the garbage collector.
  125. Other useful procs from `system <system.html>`_ you can use to keep track of memory are:
  126. * `getTotalMem()` Returns the amount of total memory managed by the garbage collector.
  127. * `getOccupiedMem()` Bytes reserved by the garbage collector and used by objects.
  128. * `getFreeMem()` Bytes reserved by the garbage collector and not in use.
  129. * `GC_getStatistics()` Garbage collector statistics as a human-readable string.
  130. These numbers are usually only for the running thread, not for the whole heap,
  131. with the exception of `--gc:boehm`:option: and `--gc:go`:option:.
  132. In addition to `GC_ref` and `GC_unref` you can avoid the garbage collector by manually
  133. allocating memory with procs like `alloc`, `alloc0`, `allocShared`, `allocShared0` or `allocCStringArray`.
  134. The garbage collector won't try to free them, you need to call their respective *dealloc* pairs
  135. (`dealloc`, `deallocShared`, `deallocCStringArray`, etc)
  136. when you are done with them or they will leak.
  137. Heap dump
  138. =========
  139. The heap dump feature is still in its infancy, but it already proved
  140. useful for us, so it might be useful for you. To get a heap dump, compile
  141. with `-d:nimTypeNames`:option: and call `dumpNumberOfInstances`
  142. at a strategic place in your program.
  143. This produces a list of the used types in your program and for every type
  144. the total amount of object instances for this type as well as the total
  145. amount of bytes these instances take up.
  146. The numbers count the number of objects in all garbage collector heaps, they refer to
  147. all running threads, not only to the current thread. (The current thread
  148. would be the thread that calls `dumpNumberOfInstances`.) This might
  149. change in later versions.