gc.rst 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. ==========================
  2. Nim's Garbage Collector
  3. ==========================
  4. :Author: Andreas Rumpf
  5. :Version: |nimversion|
  6. ..
  7. "The road to hell is paved with good intentions."
  8. Introduction
  9. ============
  10. This document describes how the GC works and how to tune it for
  11. (soft) `realtime systems`:idx:.
  12. The basic algorithm is *Deferred Reference Counting* with cycle detection.
  13. References on the stack are not counted for better performance (and easier C
  14. code generation). Cycle detection is currently done by a simple mark&sweep
  15. GC that has to scan the full (thread local heap). ``--gc:v2`` replaces this
  16. with an incremental mark and sweep. That it is not production ready yet,
  17. however.
  18. The GC is only triggered in a memory allocation operation. It is not triggered
  19. by some timer and does not run in a background thread.
  20. To force a full collection call ``GC_fullCollect``. Note that it is generally
  21. better to let the GC do its work and not enforce a full collection.
  22. Cycle collector
  23. ===============
  24. The cycle collector can be en-/disabled independently from the other parts of
  25. the GC with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``.
  26. Realtime support
  27. ================
  28. To enable realtime support, the symbol `useRealtimeGC`:idx: needs to be
  29. defined via ``--define:useRealtimeGC`` (you can put this into your config
  30. file as well). With this switch the GC supports the following operations:
  31. .. code-block:: nim
  32. proc GC_setMaxPause*(maxPauseInUs: int)
  33. proc GC_step*(us: int, strongAdvice = false, stackSize = -1)
  34. The unit of the parameters ``maxPauseInUs`` and ``us`` is microseconds.
  35. These two procs are the two modus operandi of the realtime GC:
  36. (1) GC_SetMaxPause Mode
  37. You can call ``GC_SetMaxPause`` at program startup and then each triggered
  38. GC run tries to not take longer than ``maxPause`` time. However, it is
  39. possible (and common) that the work is nevertheless not evenly distributed
  40. as each call to ``new`` can trigger the GC and thus take ``maxPause``
  41. time.
  42. (2) GC_step Mode
  43. This allows the GC to perform some work for up to ``us`` time. This is
  44. useful to call in a main loop to ensure the GC can do its work. To
  45. bind all GC activity to a ``GC_step`` call, deactivate the GC with
  46. ``GC_disable`` at program startup. If ``strongAdvice`` is set to ``true``,
  47. GC will be forced to perform collection cycle. Otherwise, GC may decide not
  48. to do anything, if there is not much garbage to collect.
  49. You may also specify the current stack size via ``stackSize`` parameter.
  50. It can improve performance, when you know that there are no unique Nim
  51. references below certain point on the stack. Make sure the size you specify
  52. is greater than the potential worst case size.
  53. These procs provide a "best effort" realtime guarantee; in particular the
  54. cycle collector is not aware of deadlines yet. Deactivate it to get more
  55. predictable realtime behaviour. Tests show that a 2ms max pause
  56. time will be met in almost all cases on modern CPUs (with the cycle collector
  57. disabled).
  58. Time measurement
  59. ----------------
  60. The GC's way of measuring time uses (see ``lib/system/timers.nim`` for the
  61. implementation):
  62. 1) ``QueryPerformanceCounter`` and ``QueryPerformanceFrequency`` on Windows.
  63. 2) ``mach_absolute_time`` on Mac OS X.
  64. 3) ``gettimeofday`` on Posix systems.
  65. As such it supports a resolution of nanoseconds internally; however the API
  66. uses microseconds for convenience.
  67. Define the symbol ``reportMissedDeadlines`` to make the GC output whenever it
  68. missed a deadline. The reporting will be enhanced and supported by the API in
  69. later versions of the collector.
  70. Tweaking the GC
  71. ---------------
  72. The collector checks whether there is still time left for its work after
  73. every ``workPackage``'th iteration. This is currently set to 100 which means
  74. that up to 100 objects are traversed and freed before it checks again. Thus
  75. ``workPackage`` affects the timing granularity and may need to be tweaked in
  76. highly specialized environments or for older hardware.
  77. Keeping track of memory
  78. -----------------------
  79. If you need to pass around memory allocated by Nim to C, you can use the
  80. procs ``GC_ref`` and ``GC_unref`` to mark objects as referenced to avoid them
  81. being freed by the GC. Other useful procs from `system <system.html>`_ you can
  82. use to keep track of memory are:
  83. * getTotalMem(): returns the amount of total memory managed by the GC.
  84. * getOccupiedMem(): bytes reserved by the GC and used by objects.
  85. * getFreeMem(): bytes reserved by the GC and not in use.
  86. In addition to ``GC_ref`` and ``GC_unref`` you can avoid the GC by manually
  87. allocating memory with procs like ``alloc``, ``allocShared``, or
  88. ``allocCStringArray``. The GC won't try to free them, you need to call their
  89. respective *dealloc* pairs when you are done with them or they will leak.
  90. Heap dump
  91. =========
  92. The heap dump feature is still in its infancy, but it already proved
  93. useful for us, so it might be useful for you. To get a heap dump, compile
  94. with ``-d:nimTypeNames`` and call ``dumpNumberOfInstances`` at a strategic place in your program.
  95. This produces a list of used types in your program and for every type
  96. the total amount of object instances for this type as well as the total
  97. amount of bytes these instances take up. This list is currently unsorted!
  98. You need to use external shell script hacking to sort it.
  99. The numbers count the number of objects in all GC heaps, they refer to
  100. all running threads, not only to the current thread. (The current thread
  101. would be the thread that calls ``dumpNumberOfInstances``.) This might
  102. change in later versions.