Frage

Ich habe Boehm GC überprüft. Der GC für C/C ++.

Ich kenne Mark-and-Sweep-Algorithmus. Ich bin neugierig, wie es nur Zeiger in der ganzen C -Erinnerung aufnimmt. Mein Verständnis für die C -Erinnerung ist nur ein einfaches Byte -Array. Ist es möglich, einen Wert im Speicher zu bestimmen, der Zeiger ist oder nicht?

War es hilfreich?

Lösung

Der Boehm GC ist ein konservativer Sammler, was bedeutet, dass alles ein Zeiger ist. Dies bedeutet, dass es falsche positive Referenzen wie eine Ganzzahl finden kann, die zufällig den Wert einer Adresse im Haufen hat. Infolgedessen können einige Blöcke länger im Gedächtnis bleiben als mit einem nicht konservativen Sammler.

Hier ist eine Beschreibung von Boehms Seite:

Der Müllsammler verwendet einen modifizierten Mark-Sweep-Algorithmus. Konzeptionell arbeitet es ungefähr in vier Phasen, die gelegentlich als Teil einer Speicherzuweisung durchgeführt werden:

  1. Vorbereitung Jedes Objekt hat ein zugeordnetes Markierbit. Löschen Sie alle Mark -Bits, was darauf hinweist, dass alle Objekte möglicherweise nicht erreichbar sind.
  2. Markieren Sie die Phase markieren alle Objekte, die über Zeigerketten aus Variablen erreichbar sind. Oft hat der Sammler keine wirklichen Informationen über den Ort der Zeigervariablen im Haufen, sodass er alle statischen Datenbereiche, Stapel und Register als potenziell enthaltene Zeiger betrachtet. Alle Bitmuster, die Adressen in vom Kollektor verwalteten Heap -Objekten darstellen, werden als Zeiger angesehen. Sofern das Client -Programm nicht dem Kollektor zur Verfügung gestellt wurde, werden alle Heap -Objekte, die von Variablen erreichbar sind, ebenso gescannt.
  3. Sweep -Phase scannt den Haufen auf unzugängliche und daher nicht markierte Objekte und gibt sie zur Wiederverwendung in eine geeignete freie Liste zurück. Dies ist nicht wirklich eine eigene Phase; Selbst im nicht inkrementellen Modus wird dieser Betrieb normalerweise während einer Zuweisung durchgeführt, die eine leere freie Liste entdeckt. Daher ist es sehr unwahrscheinlich, dass die Sweep -Phase eine Seite berührt, die sowieso nicht kurz darauf berührt worden wäre.
  4. Die für die Finalisation registrierte Abschlussphase nicht erreichbare Objekte sind für die Abschluss außerhalb des Sammlers aufgenommen.

Sie sollten auch wissen, dass der Boehm GC eine Reihe von "Wurzeln" erhalten muss, die Ausgangspunkte für den Mark-and-Sweep-Algorithmus sind. Der Stapel und die Register sind automatisch Wurzeln. Sie müssen explizit globale Zeiger als Wurzeln hinzufügen.


EDIT: In Kommentaren wurden einige Bedenken hinsichtlich konservativer Sammler im Allgemeinen darauf hingewiesen. Es ist wahr, dass Ganzzahlen, die wie Heap -Zeiger auf den Kollektor aussehen, dazu führen können, dass das Gedächtnis nicht freigegeben wird. Dies ist kein so großes Problem, wie Sie vielleicht denken. Die meisten skalaren Ganzzahlen in einem Programm werden für Zählungen und Größen verwendet und sind ziemlich klein (so würden sie nicht wie Haufenzeiger aussehen). Sie stießen hauptsächlich auf Probleme mit Arrays mit Bitmaps, Saiten, schwimmenden Punktdaten oder irgendetwas ähnlich. Mit Boehm GC können Sie einen Block zuweisen GC_MALLOC_ATOMIC Dies zeigt dem Sammler an, dass der Block keine Zeiger enthält. Wenn Sie hineinschauen gc_typed.h, Sie werden auch Wege finden, um anzugeben, welche Teile eines Blocks Zeiger enthalten können.

Eine grundlegende Einschränkung eines konservativen Sammlers besteht jedoch darin, dass er während der Sammlung den Gedächtnis nicht sicher bewegen kann, da das Umschreiben des Zeigers nicht sicher ist. Dies bedeutet, dass Sie keine der Vorteile der Verdichtung erhalten, z. B. abgesenkte Fragmentierung und verbesserte Cache -Leistung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top