Memory Management: GC, Manual and RAII
31.1 The Garbage Collector
The default allocator for new, array appends, closures, and associative arrays.
A conservative, stop-the-world, mark-and-sweep GC. It only collects during allocation, so no allocation means no GC pause.
Runtime options: --DRT-gcopt=profile:1 gc:precise parallel:4 initReserve:64 (command line or extern(C) __gshared string[] rt_options).
Alternatives: precise GC (gc:precise), the fork-based concurrent GC on Linux (gc:fork), and new GC work in progress.
import core.memory : GC;
GC.collect(); // force a collection
GC.disable(); /* ... */ GC.enable();
GC.minimize();
auto stats = GC.stats();
writeln(stats.usedSize, " ", stats.freeSize);
GC.addRoot(ptr); GC.removeRoot(ptr); // keep C-held pointers alive
GC.addRange(mem, size); // scan manually allocated memory31.2 Manual Memory Management
import core.stdc.stdlib : malloc, free, calloc, realloc;
int* p = cast(int*) malloc(10 * int.sizeof);
scope(exit) free(p);
int[] arr = p[0 .. 10]; // slice over malloc'd memory
import core.lifetime : emplace;
void[] mem = malloc(__traits(classInstanceSize, MyClass))[0 .. __traits(classInstanceSize, MyClass)];
auto obj = emplace!MyClass(mem, args); // construct in place
destroy(obj); // run the destructor
free(mem.ptr);31.3 std.experimental.allocator
Composable building blocks: FreeList, Region, StatsCollector, FallbackAllocator, Segregator, AllocatorList, BitmappedBlock.
import std.experimental.allocator;
import std.experimental.allocator.mallocator : Mallocator;
import std.experimental.allocator.building_blocks.region : Region;
auto arr = Mallocator.instance.makeArray!int(100);
scope(exit) Mallocator.instance.dispose(arr);
auto obj = Mallocator.instance.make!Point(1, 2);
scope(exit) Mallocator.instance.dispose(obj);
auto region = Region!Mallocator(1024 * 1024); // arena-style bump allocator
auto tmp = region.makeArray!ubyte(256);31.4 RAII and Reference Counting
Container libraries without the GC: automem (unique_ptr/RefCounted for D), emsi_containers, mir-algorithm (rc arrays), dplug:core.
import std.typecons : RefCounted, SafeRefCounted, Unique;
auto rc = SafeRefCounted!Buffer(1024); // freed when the last copy goes away
auto u = Unique!Resource(new Resource); // single owner31.5 @nogc Code
The compiler verifies that no GC allocation happens. -vgc lists all GC allocation points.
@nogc nothrow int sumArr(const int[] a)
{
int s = 0;
foreach (x; a) s += x;
return s; // `new`, `~`, closures, and exceptions (new Exception) aren't allowed
}