Unterstützung für zyklische Garbage Collection¶
Pythons Unterstützung für die Erkennung und Sammlung von Garbage, die zirkuläre Referenzen beinhaltet, erfordert Unterstützung von Objekttypen, die „Container“ für andere Objekte sind, welche ebenfalls Container sein können. Typen, die keine Referenzen auf andere Objekte speichern oder nur Referenzen auf atomare Typen (wie Zahlen oder Zeichenketten) speichern, müssen keine explizite Unterstützung für die Garbage Collection bereitstellen.
Um einen Containertyp zu erstellen, muss das Feld tp_flags des Typobjekts die Flags Py_TPFLAGS_HAVE_GC enthalten und eine Implementierung des tp_traverse-Handlers bereitstellen. Wenn Instanzen des Typs veränderlich sind, muss ebenfalls eine tp_clear-Implementierung bereitgestellt werden.
Py_TPFLAGS_HAVE_GCObjekte mit einem Typ, bei dem dieses Flag gesetzt ist, müssen den hier dokumentierten Regeln entsprechen. Zur Vereinfachung werden diese Objekte als Containerobjekte bezeichnet.
Konstruktoren für Containertypen müssen zwei Regeln befolgen:
Der Speicher für das Objekt muss mit
PyObject_GC_NewoderPyObject_GC_NewVaralloziert werden.Nachdem alle Felder, die Referenzen auf andere Container enthalten können, initialisiert wurden, muss
PyObject_GC_Track()aufgerufen werden.
Ebenso muss der Deallokator für das Objekt einem ähnlichen Regelpaar folgen:
Bevor Felder, die auf andere Container verweisen, ungültig gemacht werden, muss
PyObject_GC_UnTrack()aufgerufen werden.Der Speicher des Objekts muss mit
PyObject_GC_Del()freigegeben werden.Warnung
Wenn ein Typ Py_TPFLAGS_HAVE_GC hinzufügt, dann *muss* er mindestens einen
tp_traverse-Handler implementieren oder explizit einen von seiner Unterklasse oder Unterklassen verwenden.Beim Aufruf von
PyType_Ready()oder einiger APIs, die es indirekt aufrufen, wiePyType_FromSpecWithBases()oderPyType_FromSpec(), wird der Interpreter automatisch die Feldertp_flags,tp_traverseundtp_clearfüllen, wenn der Typ von einer Klasse erbt, die das Garbage-Collector-Protokoll implementiert, und die Kindklasse das FlagPy_TPFLAGS_HAVE_GC*nicht* enthält.
-
PyObject_GC_New(TYPE, typeobj)¶
Analog zu
PyObject_New, aber für Containerobjekte mit gesetztem FlagPy_TPFLAGS_HAVE_GC.Rufen Sie diese Funktion nicht direkt auf, um Speicher für ein Objekt zu allozieren; rufen Sie stattdessen den
tp_alloc-Slot des Typs auf.Beim Füllen des
tp_alloc-Slots eines Typs wirdPyType_GenericAlloc()einer benutzerdefinierten Funktion vorgezogen, die einfach dieses Makro aufruft.Mit diesem Makro allozierter Speicher muss mit
PyObject_GC_Del()(normalerweise über dentp_free-Slot des Objekts aufgerufen) freigegeben werden.
-
PyObject_GC_NewVar(TYPE, typeobj, size)¶
Analog zu
PyObject_NewVar, aber für Containerobjekte mit gesetztem FlagPy_TPFLAGS_HAVE_GC.Rufen Sie diese Funktion nicht direkt auf, um Speicher für ein Objekt zu allozieren; rufen Sie stattdessen den
tp_alloc-Slot des Typs auf.Beim Füllen des
tp_alloc-Slots eines Typs wirdPyType_GenericAlloc()einer benutzerdefinierten Funktion vorgezogen, die einfach dieses Makro aufruft.Mit diesem Makro allozierter Speicher muss mit
PyObject_GC_Del()(normalerweise über dentp_free-Slot des Objekts aufgerufen) freigegeben werden.
-
PyObject *PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *type, size_t extra_size)¶
- Dies ist eine Instabile API. Sie kann sich ohne Vorwarnung in kleineren Releases ändern.
Analog zu
PyObject_GC_New, aber alloziert *extra_size* Bytes am Ende des Objekts (an Offsettp_basicsize). Der allozierte Speicher wird mit Nullen initialisiert, mit Ausnahme desPython-Objekt-Headers.Die zusätzlichen Daten werden zusammen mit dem Objekt freigegeben, sind aber ansonsten nicht von Python verwaltet.
Mit dieser Funktion allozierter Speicher muss mit
PyObject_GC_Del()(normalerweise über dentp_free-Slot des Objekts aufgerufen) freigegeben werden.Warnung
Die Funktion ist als instabil markiert, da der endgültige Mechanismus zur Reservierung zusätzlicher Daten nach einer Instanz noch nicht festgelegt ist. Für die Allokation einer variablen Anzahl von Feldern ist es vorzuziehen, stattdessen
PyVarObjectundtp_itemsizezu verwenden.Hinzugefügt in Version 3.12.
-
PyObject_GC_Resize(TYPE, op, newsize)¶
Ändert die Größe eines von
PyObject_NewVaralloziierten Objekts. Gibt das geänderte Objekt vom TypTYPE*(bezieht sich auf jeden C-Typ) oderNULLim Fehlerfall zurück.op muss vom Typ PyVarObject* sein und darf noch nicht vom Collector verfolgt werden. newsize muss vom Typ
Py_ssize_tsein.
-
void PyObject_GC_Track(PyObject *op)¶
- Teil der Stable ABI.
Fügt das Objekt op zur Menge der vom Collector verfolgten Containerobjekte hinzu. Der Collector kann zu unerwarteten Zeiten laufen, daher müssen Objekte gültig sein, während sie verfolgt werden. Dies sollte einmal geschehen, nachdem alle Felder, die vom
tp_traverse-Handler verfolgt werden, gültig geworden sind, normalerweise gegen Ende des Konstruktors.
-
int PyObject_IS_GC(PyObject *obj)¶
Gibt einen Wert ungleich Null zurück, wenn das Objekt das Garbage-Collector-Protokoll implementiert, andernfalls 0.
Das Objekt kann nicht vom Garbage Collector verfolgt werden, wenn diese Funktion 0 zurückgibt.
-
int PyObject_GC_IsTracked(PyObject *op)¶
- Teil der Stable ABI seit Version 3.9.
Gibt 1 zurück, wenn der Objekttyp von op das GC-Protokoll implementiert und op gerade vom Garbage Collector verfolgt wird, andernfalls 0.
Dies ist analog zur Python-Funktion
gc.is_tracked().Hinzugefügt in Version 3.9.
-
int PyObject_GC_IsFinalized(PyObject *op)¶
- Teil der Stable ABI seit Version 3.9.
Gibt 1 zurück, wenn der Objekttyp von op das GC-Protokoll implementiert und op bereits vom Garbage Collector finalisiert wurde, andernfalls 0.
Dies ist analog zur Python-Funktion
gc.is_finalized().Hinzugefügt in Version 3.9.
-
void PyObject_GC_Del(void *op)¶
- Teil der Stable ABI.
Gibt mit
PyObject_GC_NewoderPyObject_GC_NewVaralloziierten Speicher für ein Objekt frei.Rufen Sie diese Funktion nicht direkt auf, um den Speicher eines Objekts freizugeben; rufen Sie stattdessen den
tp_free-Slot des Typs auf.Verwenden Sie diese Funktion nicht für Speicher, der mit
PyObject_New,PyObject_NewVaroder verwandten Allokationsfunktionen alloziert wurde; verwenden Sie stattdessenPyObject_Free().Siehe auch
PyObject_Free()ist das Nicht-GC-Äquivalent dieser Funktion.
-
void PyObject_GC_UnTrack(void *op)¶
- Teil der Stable ABI.
Entfernt das Objekt op aus der Menge der vom Collector verfolgten Containerobjekte. Beachten Sie, dass
PyObject_GC_Track()erneut für dieses Objekt aufgerufen werden kann, um es wieder zur Menge der verfolgten Objekte hinzuzufügen. Der Deallokator (tp_dealloc-Handler) sollte dies für das Objekt aufrufen, bevor eines der vomtp_traverse-Handler verwendeten Felder ungültig wird.
Geändert in Version 3.8: Die Makros _PyObject_GC_TRACK() und _PyObject_GC_UNTRACK() wurden aus der öffentlichen C-API entfernt.
Der tp_traverse-Handler akzeptiert einen Funktionsparameter dieses Typs.
-
typedef int (*visitproc)(PyObject *object, void *arg)¶
- Teil der Stable ABI.
Typ der Besucherfunktion, die an den
tp_traverse-Handler übergeben wird. Die Funktion sollte mit einem zu durchlaufenden Objekt als object und dem dritten Parameter destp_traverse-Handlers als arg aufgerufen werden. Der Python-Kern verwendet mehrere Besucherfunktionen zur Implementierung der zyklischen Garbage-Erkennung; es wird nicht erwartet, dass Benutzer eigene Besucherfunktionen schreiben.
Der tp_traverse-Handler muss den folgenden Typ haben:
-
typedef int (*traverseproc)(PyObject *self, visitproc visit, void *arg)¶
- Teil der Stable ABI.
Traversierungsfunktion für ein Containerobjekt. Implementierungen müssen die visit-Funktion für jedes Objekt aufrufen, das direkt von self enthalten ist, wobei die Parameter für visit das enthaltene Objekt und der an den Handler übergebene arg-Wert sind. Die visit-Funktion darf nicht mit einem
NULL-Objektargument aufgerufen werden. Wenn visit einen Wert ungleich Null zurückgibt, sollte dieser Wert sofort zurückgegeben werden.
Um das Schreiben von tp_traverse-Handlern zu vereinfachen, wird ein Makro Py_VISIT() bereitgestellt. Um dieses Makro verwenden zu können, muss die tp_traverse-Implementierung ihre Argumente exakt *visit* und *arg* nennen.
-
Py_VISIT(o)¶
Wenn das PyObject* o nicht
NULList, rufe den visit-Callback mit den Argumenten o und arg auf. Wenn visit einen Wert ungleich Null zurückgibt, gib diesen zurück. Mit diesem Makro sehentp_traverse-Handler wie folgt aus:static int my_traverse(Noddy *self, visitproc visit, void *arg) { Py_VISIT(self->foo); Py_VISIT(self->bar); return 0; }
Der tp_clear-Handler muss vom Typ inquiry sein oder NULL, wenn das Objekt unveränderlich ist.
-
typedef int (*inquiry)(PyObject *self)¶
- Teil der Stable ABI.
Referenzen löschen, die möglicherweise Referenzzyklen erzeugt haben. Unveränderliche Objekte müssen diese Methode nicht definieren, da sie niemals direkt Referenzzyklen erzeugen können. Beachten Sie, dass das Objekt nach dem Aufruf dieser Methode noch gültig sein muss (rufen Sie nicht einfach
Py_DECREF()für eine Referenz auf). Der Collector ruft diese Methode auf, wenn er erkennt, dass dieses Objekt an einem Referenzzyklus beteiligt ist.
Steuerung des Zustands des Garbage Collectors¶
Die C-API stellt die folgenden Funktionen zur Steuerung von Garbage-Collection-Läufen bereit.
-
Py_ssize_t PyGC_Collect(void)¶
- Teil der Stable ABI.
Führt eine vollständige Garbage Collection durch, wenn der Garbage Collector aktiviert ist. (Hinweis:
gc.collect()führt sie bedingungslos aus.)Gibt die Anzahl der gesammelten + nicht erreichbaren Objekte zurück, die nicht gesammelt werden können. Wenn der Garbage Collector deaktiviert ist oder bereits sammelt, gibt er sofort
0zurück. Fehler während der Garbage Collection werden ansys.unraisablehookübergeben. Diese Funktion löst keine Ausnahmen aus.
-
int PyGC_Enable(void)¶
- Teil der Stable ABI seit Version 3.10.
Aktiviert den Garbage Collector: ähnlich wie
gc.enable(). Gibt den vorherigen Zustand zurück, 0 für deaktiviert und 1 für aktiviert.Hinzugefügt in Version 3.10.
-
int PyGC_Disable(void)¶
- Teil der Stable ABI seit Version 3.10.
Deaktiviert den Garbage Collector: ähnlich wie
gc.disable(). Gibt den vorherigen Zustand zurück, 0 für deaktiviert und 1 für aktiviert.Hinzugefügt in Version 3.10.
-
int PyGC_IsEnabled(void)¶
- Teil der Stable ABI seit Version 3.10.
Fragt den Zustand des Garbage Collectors ab: ähnlich wie
gc.isenabled(). Gibt den aktuellen Zustand zurück, 0 für deaktiviert und 1 für aktiviert.Hinzugefügt in Version 3.10.
Abfragen des Zustands des Garbage Collectors¶
Die C-API stellt die folgende Schnittstelle zur Abfrage von Informationen über den Garbage Collector bereit.
-
void PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg)¶
- Dies ist eine Instabile API. Sie kann sich ohne Vorwarnung in kleineren Releases ändern.
Führt den bereitgestellten callback für alle lebenden GC-fähigen Objekte aus. arg wird an alle Aufrufe von callback weitergegeben.
Warnung
Wenn während des Callbacks neue Objekte (de-)alloziert werden, ist es undefiniert, ob sie besucht werden.
Die Garbage Collection ist während des Betriebs deaktiviert. Ein expliziter Aufruf einer Collection im Callback kann zu undefiniertem Verhalten führen, z. B. dazu, dass dieselben Objekte mehrmals oder gar nicht besucht werden.
Hinzugefügt in Version 3.12.
-
typedef int (*gcvisitobjects_t)(PyObject *object, void *arg)¶
Typ der Besucherfunktion, die an
PyUnstable_GC_VisitObjects()zu übergeben ist. arg ist dasselbe wie das arg, das anPyUnstable_GC_VisitObjectsübergeben wird. Rückgabe von1zum Fortsetzen der Iteration, Rückgabe von0zum Stoppen der Iteration. Andere Rückgabewerte sind derzeit reserviert, daher ist das Verhalten bei Rückgabe anderer Werte undefiniert.Hinzugefügt in Version 3.12.