core.memory

  • This module provides an interface to the garbage collector used by
  • applications written in the D programming language. It allows the
  • garbage collector in the runtime to be swapped without affecting
  • binary compatibility of applications.
  • Using this module is not necessary in typical D code. It is mostly
  • useful when doing low-level _memory management.
  • Notes_to_users: *
    1. The GC is a conservative mark-and-sweep collector. It only runs a collection cycle when an allocation is requested of it, never otherwise. Hence, if the program is not doing allocations, there will be no GC collection pauses. The pauses occur because all threads the GC knows about are halted so the threads' stacks and registers can be scanned for references to GC allocated data.
  • The GC does not know about threads that were created by directly calling

    the OS/C runtime thread creation APIs and D threads that were detached from the D runtime after creation. Such threads will not be paused for a GC collection, and the GC might not detect references to GC allocated data held by them. This can cause memory corruption. There are several ways to resolve this issue:

    1. Do not hold references to GC allocated data in such threads.
    2. Register/unregister such data with calls to addRoot/removeRoot and

      addRange/removeRange.

    3. Maintain another reference to that same data in another thread that the

      GC does know about.

    4. Disable GC collection cycles while that thread is active with disable/enable.
    5. Register the thread with the GC using thread_attachThis/thread_detachThis.
  • *

    • Notes_to_implementors:
      • On POSIX systems, the signals SIGRTMIN and SIGRTMIN + 1 are reserved
      • by this module for use in the garbage collector implementation.
      • Typically, they will be used to stop and resume other threads
      • when performing a collection, but an implementation may choose
      • not to use this mechanism (or not stop the world at all, in the
      • case of concurrent garbage collectors).
      • Registers, the stack, and any other _memory locations added through
      • the GC.addRange function are always scanned conservatively.
      • This means that even if a variable is e.g. of type float,
      • it will still be scanned for possible GC pointers. And, if the
      • word-interpreted representation of the variable matches a GC-managed
      • _memory block's address, that _memory block is considered live.
      • Implementations are free to scan the non-root heap in a precise
      • manner, so that fields of types like float will not be considered
      • relevant when scanning the heap. Thus, casting a GC pointer to an
      • integral type (e.g. size_t) and storing it in a field of that
      • type inside the GC heap may mean that it will not be recognized
      • if the _memory block was allocated with precise type info or with
      • the GC.BlkAttr.NO_SCAN attribute.
      • Destructors will always be executed while other threads are
      • active; that is, an implementation that stops the world must not
      • execute destructors until the world has been resumed.
      • A destructor of an object must not access object references
      • within the object. This means that an implementation is free to
      • optimize based on this rule.
      • An implementation is free to perform heap compaction and copying
      • so long as no valid GC pointers are invalidated in the process.
      • However, _memory allocated with GC.BlkAttr.NO_MOVE must
      • not be moved/copied.
      • Implementations must support interior pointers. That is, if the
      • only reference to a GC-managed _memory block points into the
      • middle of the block rather than the beginning (for example), the
      • GC must consider the _memory block live. The exception to this
      • rule is when a _memory block is allocated with the
      • GC.BlkAttr.NO_INTERIOR attribute; it is the user's
      • responsibility to make sure such _memory blocks have a proper pointer
      • to them when they should be considered live.
      • It is acceptable for an implementation to store bit flags into
      • pointer values and GC-managed _memory blocks, so long as such a
      • trick is not visible to the application. In practice, this means
      • that only a stop-the-world collector can do this.
      • Implementations are free to assume that GC pointers are only
      • stored on word boundaries. Unaligned pointers may be ignored
      • entirely.
      • Implementations are free to run collections at any point. It is,
      • however, recommendable to only do so when an allocation attempt
      • happens and there is insufficient _memory available.
    • Source: core/_memory.d