The garbage collector

The GC has been a background presence throughout this book, occasionally coming to the fore when we discussed specific language and library features. For a large number of D programs, it is never necessary to interact directly with the GC. A programmer needs to be aware of when collection cycles may occur, how to write GC-free code with @nogc, and how to avoid the potential issues that may arise when using GC-managed memory with C libraries, but the need to get down and dirty with the GC API is rare. When those times do arise, the core.memory module comes into play.

In this module, you'll find a single structure, GC, which contains a number of static member functions. Automatic garbage collection can be turned off with GC.disable. This doesn't turn off the GC completely—it will still run when the system is out of memory—but it does prevent it from running during normal usage. Collection can be forced by calling GC.collect. There have been reports of significant performance increases for some applications when turning off automatic collection in favor of manual collection. Automatic collection can be turned on again at any time with GC.enable.

Now and again, it's necessary to ensure that a block of memory hangs around indefinitely, or until the programmer determines it's no longer needed. One such scenario was presented in Chapter 9, Connecting D with C; when a block of memory allocated by the GC on the D side is handed off for a C library to make use of, bad things can happen if the GC collects the memory before the C code is finished with it. Passing a pointer to the memory to GC.addRoot will guarantee the memory block remains alive indefinitely. When GC.removeRoot is called, the GC will then be free to collect the memory block at any time.

Normally, GC memory is allocated indirectly though the new operator, expanding the capacity of dynamic arrays, or other language features. However, it's possible to allocate memory from the GC directly via GC.malloc. With this function, flags from the GC.BlkAttr enumeration can be used to control how the GC treats the memory, giving the programmer more fine-tuned control; when you know a block of memory contains no pointers to GC-managed memory, it's a waste of cycles for the GC to scan it again and again.

Sometimes, it's necessary to allocate memory outside of the GC, such as through a third-party C library or one of the standard C library allocators (such as malloc), that will be used to store pointers to memory allocated through the GC, such as class references or dynamic arrays. In this case, the memory block can be registered with the GC via the GC.addRange function. This will add the block to the list of memory locations the GC will scan. When the memory is no longer needed, GC.removeRange can be called to remove it from the GC's list.

As an aid in tuning the GC usage of a D application, DMD provides the -vgc command-line switch, which lists all of the GC allocations that can occur in a program. This includes hidden allocations, such as those that happen under the hood with dynamic arrays or inside Phobos functions. When the garbage collector starts to become a performance issue in a D program, as it sometimes may, this switch can be used to help guide manual optimizations, such as the addition of @nogc where appropriate and the use of GC member functions like disable and collect. For more on D's garbage collector, refer to http://dlang.org/phobos/core_memory.html and http://dlang.org/garbage.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.173.199