Stöd för cyklisk skräpinsamling

Pythons stöd för att upptäcka och samla in skräp som involverar cirkulära referenser kräver stöd från objekttyper som är ”behållare” för andra objekt som också kan vara behållare. Typer som inte lagrar referenser till andra objekt, eller som bara lagrar referenser till atomära typer (t.ex. tal eller strängar), behöver inte tillhandahålla något explicit stöd för skräpinsamling.

För att skapa en containertyp måste fältet tp_flags i typobjektet innehålla Py_TPFLAGS_HAVE_GC och tillhandahålla en implementation av hanteraren tp_traverse. Om instanser av typen är mutabla måste också en implementation av tp_clear tillhandahållas.

Py_TPFLAGS_HAVE_GC

Objekt med en typ med denna flagga måste följa de regler som dokumenteras här. För enkelhetens skull kommer dessa objekt att kallas containerobjekt.

Konstruktörer för containertyper måste följa två regler:

  1. Minnet för objektet måste allokeras med hjälp av PyObject_GC_New eller PyObject_GC_NewVar.

  2. När alla fält, som kan innehålla referenser till andra containrar, har initialiserats måste den anropa PyObject_GC_Track().

På samma sätt måste deallokatorn för objektet följa ett liknande par regler:

  1. Innan fält som hänvisar till andra behållare ogiltigförklaras måste PyObject_GC_UnTrack() anropas.

  2. Objektets minne måste avallokeras med hjälp av PyObject_GC_Del().

    Varning

    Om en typ lägger till Py_TPFLAGS_HAVE_GC, så måste den implementera minst en tp_traverse-hanterare eller uttryckligen använda en från sin underklass eller underklasser.

    När man anropar PyType_Ready() eller några av de API:er som indirekt anropar det som PyType_FromSpecWithBases() eller PyType_FromSpec() kommer tolken automatiskt att fylla i fälten tp_flags, tp_traverse och tp_clear om typen ärver från en klass som implementerar garbage collector-protokollet och den underordnade klassen inte innehåller flaggan Py_TPFLAGS_HAVE_GC.

PyObject_GC_New(TYPE, typeobj)

Analogt med PyObject_New men för containerobjekt med flaggan Py_TPFLAGS_HAVE_GC inställd.

Anropa inte detta direkt för att allokera minne för ett objekt; anropa istället typens tp_alloc slot.

När en typs tp_alloc-plats fylls i är PyType_GenericAlloc() att föredra framför en anpassad funktion som helt enkelt anropar detta makro.

Minne som allokerats av detta makro måste frigöras med PyObject_GC_Del() (anropas vanligtvis via objektets tp_free slot).

PyObject_GC_NewVar(TYPE, typeobj, size)

Analogt med PyObject_NewVar men för containerobjekt med flaggan Py_TPFLAGS_HAVE_GC inställd.

Anropa inte detta direkt för att allokera minne för ett objekt; anropa istället typens tp_alloc slot.

När en typs tp_alloc-plats fylls i är PyType_GenericAlloc() att föredra framför en anpassad funktion som helt enkelt anropar detta makro.

Minne som allokerats av detta makro måste frigöras med PyObject_GC_Del() (anropas vanligtvis via objektets tp_free slot).

PyObject *PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *type, size_t extra_size)
Detta är Instabilt API. Den kan ändras utan förvarning i mindre versioner.

Analogt med PyObject_GC_New men allokerar extra_size bytes i slutet av objektet (vid offset tp_basicsize). Det allokerade minnet initialiseras till noll, förutom Python object header.

Den extra datan kommer att avallokeras med objektet, men i övrigt hanteras den inte av Python.

Minne som allokerats av denna funktion måste frigöras med PyObject_GC_Del() (anropas vanligtvis via objektets tp_free slot).

Varning

Funktionen är markerad som instabil eftersom den slutliga mekanismen för att reservera extra data efter en instans ännu inte är bestämd. För att allokera ett varierande antal fält, använd hellre PyVarObject och tp_itemsize istället.

Tillagd i version 3.12.

PyObject_GC_Resize(TYPE, op, newsize)

Ändrar storlek på ett objekt som allokerats av PyObject_NewVar. Returnerar det storleksändrade objektet av typen TYPE* (refererar till valfri C-typ) eller NULL om det misslyckas.

op måste vara av typen PyVarObject* och får inte spåras av samlaren ännu. newsize måste vara av typen Py_ssize_t.

void PyObject_GC_Track(PyObject *op)
En del av Stabil ABI.

Lägger till objektet op till uppsättningen containerobjekt som spåras av samlaren. Uppsamlaren kan köras vid oväntade tidpunkter så objekten måste vara giltiga när de spåras. Detta bör anropas när alla fält som följs av handlaren tp_traverse blir giltiga, vanligtvis i slutet av konstruktorn.

int PyObject_IS_GC(PyObject *obj)

Returnerar icke-noll om objektet implementerar garbage collector-protokollet, annars returneras 0.

Objektet kan inte spåras av skräpsamlaren om denna funktion returnerar 0.

int PyObject_GC_IsTracked(PyObject *op)
En del av Stabil ABI sedan version 3.9.

Returnerar 1 om objekttypen för op implementerar GC-protokollet och op för närvarande spåras av skräpsamlaren och 0 i annat fall.

Detta är analogt med Python-funktionen gc.is_tracked().

Tillagd i version 3.9.

int PyObject_GC_IsFinalized(PyObject *op)
En del av Stabil ABI sedan version 3.9.

Returnerar 1 om objekttypen för op implementerar GC-protokollet och op redan har slutförts av skräpsamlaren och 0 i annat fall.

Detta är analogt med Python-funktionen gc.is_finalized().

Tillagd i version 3.9.

void PyObject_GC_Del(void *op)
En del av Stabil ABI.

Frigör minne som allokerats till ett objekt med PyObject_GC_New eller PyObject_GC_NewVar.

Anropa inte detta direkt för att frigöra ett objekts minne; anropa istället typens tp_free slot.

Använd inte detta för minne som allokerats av PyObject_New, PyObject_NewVar eller relaterade allokeringsfunktioner; använd istället PyObject_Free().

Se även

void PyObject_GC_UnTrack(void *op)
En del av Stabil ABI.

Ta bort objektet op från uppsättningen containerobjekt som spåras av samlaren. Observera att PyObject_GC_Track() kan anropas igen på detta objekt för att lägga till det igen i uppsättningen av spårade objekt. Deallocatorn (tp_dealloc handler) bör anropa detta för objektet innan något av de fält som används av tp_traverse handler blir ogiltigt.

Ändrad i version 3.8: Makron _PyObject_GC_TRACK() och _PyObject_GC_UNTRACK() har tagits bort från det publika C API:et.

Hanteraren tp_traverse accepterar en funktionsparameter av denna typ:

typedef int (*visitproc)(PyObject *object, void *arg)
En del av Stabil ABI.

Typ av besöksfunktion som skickas till tp_traverse handler. Funktionen bör anropas med ett objekt att traversera som object och den tredje parametern till handläggaren tp_traverse som arg. Python-kärnan använder flera besökarfunktioner för att implementera cyklisk skräpdetektering; det förväntas inte att användare behöver skriva sina egna besökarfunktioner.

Hanteraren tp_traverse måste ha följande typ:

typedef int (*traverseproc)(PyObject *self, visitproc visit, void *arg)
En del av Stabil ABI.

Traversalfunktion för ett containerobjekt. Implementeringar måste anropa funktionen visit för varje objekt som direkt ingår i self, där parametrarna till visit är det ingående objektet och värdet för arg som skickas till hanteraren. Funktionen visit får inte anropas med ett NULL objektargument. Om visit returnerar ett värde som inte är noll ska detta värde returneras omedelbart.

För att förenkla skrivandet av tp_traverse-hanterare tillhandahålls ett Py_VISIT()-makro. För att kunna använda detta makro måste tp_traverse implementationen namnge sina argument exakt visit och arg:

Py_VISIT(o)

Om PyObject* o inte är NULL, anropa visit callback, med argumenten o och arg. Om visit returnerar ett värde som inte är noll, returnera det. Med hjälp av detta makro ser tp_traverse handlers ut som:

static int
my_traverse(Noddy *self, visitproc visit, void *arg)
{
    Py_VISIT(self->foo);
    Py_VISIT(self->bar);
    return 0;
}

Hanteraren tp_clear måste vara av typen inquiry, eller NULL om objektet är oföränderligt.

typedef int (*inquiry)(PyObject *self)
En del av Stabil ABI.

Släpper referenser som kan ha skapat referenscykler. Oföränderliga objekt behöver inte definiera denna metod eftersom de aldrig direkt kan skapa referenscykler. Observera att objektet fortfarande måste vara giltigt efter anropet av denna metod (anropa inte bara Py_DECREF() på en referens). Uppsamlaren anropar denna metod om den upptäcker att detta objekt är involverat i en referenscykel.

Styrning av skräpsamlarens tillstånd

C-API tillhandahåller följande funktioner för att styra körningar av skräpplockning.

Py_ssize_t PyGC_Collect(void)
En del av Stabil ABI.

Utför en fullständig skräpinsamling, om skräpinsamlaren är aktiverad. (Observera att gc.collect() kör den villkorslöst)

Returnerar antalet insamlade + oåtkomliga objekt som inte kan samlas in. Om skräpsamlaren är inaktiverad eller redan samlar in objekt, returneras 0 omedelbart. Fel under skräpinsamlingen skickas till sys.unraisablehook. Denna funktion ger inte upphov till undantag.

int PyGC_Enable(void)
En del av Stabil ABI sedan version 3.10.

Aktivera skräpsamlaren: liknar gc.enable(). Returnerar det tidigare tillståndet, 0 för inaktiverad och 1 för aktiverad.

Tillagd i version 3.10.

int PyGC_Disable(void)
En del av Stabil ABI sedan version 3.10.

Inaktivera skräpsamlaren: liknar gc.disable(). Returnerar det tidigare tillståndet, 0 för inaktiverad och 1 för aktiverad.

Tillagd i version 3.10.

int PyGC_IsEnabled(void)
En del av Stabil ABI sedan version 3.10.

Frågar efter skräpsamlarens tillstånd: liknar gc.isenabled(). Returnerar det aktuella tillståndet, 0 för inaktiverad och 1 för aktiverad.

Tillagd i version 3.10.

Förfrågan om status för skräpsamlare

C-API tillhandahåller följande gränssnitt för att fråga efter information om skräpsamlaren.

void PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg)
Detta är Instabilt API. Den kan ändras utan förvarning i mindre versioner.

Kör medföljande callback på alla levande GC-kompatibla objekt. arg skickas vidare till alla anrop av callback.

Varning

Om nya objekt (de)allokeras av callbacken är det inte fastställt om de kommer att besökas.

Garbage collection är inaktiverad under drift. Att explicit köra en insamling i återuppringningen kan leda till odefinierat beteende, t.ex. att samma objekt besöks flera gånger eller inte alls.

Tillagd i version 3.12.

typedef int (*gcvisitobjects_t)(PyObject *object, void *arg)

Typ av besöksfunktion som ska skickas till PyUnstable_GC_VisitObjects(). arg är samma som arg som skickas till PyUnstable_GC_VisitObjects. Returnera 1 för att fortsätta iterationen, returnera 0 för att stoppa iterationen. Andra returvärden är reserverade för tillfället så beteendet vid retur av något annat är odefinierat.

Tillagd i version 3.12.