- Fürchte den Schnitter nicht
- Leben auf der Überholspur
- Gehen Sie Ihren eigenen Weg. Teil eins. Stapel
- Gehen Sie Ihren eigenen Weg. Zweiter Teil. Haufen
D wird, wie viele heute weit verbreitete Sprachen, mit einem Garbage Collector (GC) geliefert. Viele Arten von Software können entwickelt werden, ohne an GC zu denken, und ihre Vorteile voll ausnutzen. GC hat jedoch seine Mängel und die Speicherbereinigung ist in einigen Szenarien nicht wünschenswert. In solchen Fällen können Sie mit der Sprache den Garbage Collector vorübergehend deaktivieren oder sogar ganz darauf verzichten.
Um das Beste aus dem Garbage Collector herauszuholen und seine Nachteile zu minimieren, müssen Sie verstehen, wie der GC in der D-Sprache funktioniert. Ein guter Ausgangspunkt ist die Garbage Collection-Seite auf dlang.org , auf der die Gründe für den GC in der D-Sprache erläutert werden Tipps, wie man damit arbeitet. Dies ist der erste einer Reihe von Artikeln, die das Thema ausführlicher behandeln.
Dieses Mal werden wir nur die Grundlagen ansprechen und uns auf die Sprachfunktionen konzentrieren, die eine Speicherzuweisung durch den GC verursachen können. In zukünftigen Artikeln werden Möglichkeiten zum Deaktivieren von GC bei Bedarf sowie Redewendungen zum Umgang mit dem Nichtdeterminismus (z. B. Ressourcenmanagement in von GC kontrollierten Objektdestruktoren) vorgestellt.
Das allererste, was geklärt werden muss: Der Garbage Collector in D wird nur während der Speicherzuweisung ausgeführt und nur, wenn kein Speicher zugewiesen werden kann. Er sitzt nicht im Hintergrund, scannt regelmäßig den Stapel und sammelt Müll. Sie müssen dies verstehen, um GC-gesteuerten speichereffizienten Code schreiben zu können. Betrachten Sie das folgende Beispiel:
void main() {
int[] ints;
foreach(i; 0..100) {
ints ~= i;
}
}
Dieses Programm erstellt ein dynamisches Array von Typwerten int
und fügt dann mit dem Verknüpfungsoperator in D Zahlen von 0 bis 99 Zoll hinzu foreach
. Was für das ungeübte Auge nicht offensichtlich ist, ist, dass der Join-Operator Speicher für zusätzliche Werte über den Garbage Collector zuweist.
D . , . , , . , , capacity
. , , .
void main() {
import std.stdio : writefln;
int[] ints;
size_t before, after;
foreach(i; 0..100) {
before = ints.capacity;
ints ~= i;
after = ints.capacity;
if(before != after) {
writefln("Before: %s After: %s",
before, after);
}
}
}
DMD 2.073.2, — GC. , GC . . , GC, .
, before
after
. : 0, 3, 7, 15, 31, 63, 127. ints
100 , 27 , , 255, . , , D, . , GC , (Steve Schveighoffer) .
, , GC . , , «» . GC .
, C C++, , . , — , . , GC D , . :
void main() {
int[] ints = new int[](100);
foreach(i; 0..100) {
ints[i] = i;
}
}
. , — . 100 . new
100, .
: reserve
:
void main() {
int[] ints;
ints.reserve(100);
foreach(i; 0..100) {
ints ~= i;
}
}
100 , ( length
0), . , 100 , , .
new
reserve
, , GC.malloc
.
import core.memory;
void* intsPtr = GC.malloc(int.sizeof * 100);
auto ints = (cast(int*)intsPtr)[0 .. 100];
auto ints = [0, 1, 2];
, enum
.
enum intsLiteral = [0, 1, 2];
auto ints1 = intsLiteral;
auto ints2 = intsLiteral;
enum
. — . , . ints1
, ints2
, :
auto ints1 = [0, 1, 2];
auto ints2 = [0, 1, 2];
int[3] noAlloc1 = [0, 1, 2];
auto noAlloc2 = "No Allocation!";
:
auto a1 = [0, 1, 2];
auto a2 = [3, 4, 5];
auto a3 = a1 ~ a2;
D , , . : keys
values
, . , , - , — . , GC.
- , , , . , . , . D : byKey
, byValue
byKeyValue
. , . , , . Ranges More Range (Ali Çehreli) Programming in D.
— , — . , Garbage Collection — assert
. , assert
, AssertError
, D, ( , GC).
, Phobos — D. - - Phobos’ GC, , . , Phobos GC. , , , , , . GC (, , , — - ).
Nachdem wir uns mit den Grundlagen der Arbeit mit GC vertraut gemacht haben, werden wir im nächsten Artikel dieser Reihe sehen, mit welchen Tools in der Sprache und im Compiler wir den Garbage Collector deaktivieren und sicherstellen können, dass kritische Bereiche des Programms nicht auf den GC zugreifen.
Vielen Dank an Guillaume Piolat und Steve Schweichoffer für ihre Hilfe bei der Vorbereitung dieses Artikels.