17db96d56Sopenharmony_ci.. highlight:: c 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci.. _supporting-cycle-detection: 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ciSupporting Cyclic Garbage Collection 67db96d56Sopenharmony_ci==================================== 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ciPython's support for detecting and collecting garbage which involves circular 97db96d56Sopenharmony_cireferences requires support from object types which are "containers" for other 107db96d56Sopenharmony_ciobjects which may also be containers. Types which do not store references to 117db96d56Sopenharmony_ciother objects, or which only store references to atomic types (such as numbers 127db96d56Sopenharmony_cior strings), do not need to provide any explicit support for garbage 137db96d56Sopenharmony_cicollection. 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ciTo create a container type, the :c:member:`~PyTypeObject.tp_flags` field of the type object must 167db96d56Sopenharmony_ciinclude the :const:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the 177db96d56Sopenharmony_ci:c:member:`~PyTypeObject.tp_traverse` handler. If instances of the type are mutable, a 187db96d56Sopenharmony_ci:c:member:`~PyTypeObject.tp_clear` implementation must also be provided. 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci.. data:: Py_TPFLAGS_HAVE_GC 227db96d56Sopenharmony_ci :noindex: 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci Objects with a type with this flag set must conform with the rules 257db96d56Sopenharmony_ci documented here. For convenience these objects will be referred to as 267db96d56Sopenharmony_ci container objects. 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ciConstructors for container types must conform to two rules: 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci#. The memory for the object must be allocated using :c:func:`PyObject_GC_New` 317db96d56Sopenharmony_ci or :c:func:`PyObject_GC_NewVar`. 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci#. Once all the fields which may contain references to other containers are 347db96d56Sopenharmony_ci initialized, it must call :c:func:`PyObject_GC_Track`. 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ciSimilarly, the deallocator for the object must conform to a similar pair of 377db96d56Sopenharmony_cirules: 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci#. Before fields which refer to other containers are invalidated, 407db96d56Sopenharmony_ci :c:func:`PyObject_GC_UnTrack` must be called. 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci#. The object's memory must be deallocated using :c:func:`PyObject_GC_Del`. 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci .. warning:: 457db96d56Sopenharmony_ci If a type adds the Py_TPFLAGS_HAVE_GC, then it *must* implement at least 467db96d56Sopenharmony_ci a :c:member:`~PyTypeObject.tp_traverse` handler or explicitly use one 477db96d56Sopenharmony_ci from its subclass or subclasses. 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci When calling :c:func:`PyType_Ready` or some of the APIs that indirectly 507db96d56Sopenharmony_ci call it like :c:func:`PyType_FromSpecWithBases` or 517db96d56Sopenharmony_ci :c:func:`PyType_FromSpec` the interpreter will automatically populate the 527db96d56Sopenharmony_ci :c:member:`~PyTypeObject.tp_flags`, :c:member:`~PyTypeObject.tp_traverse` 537db96d56Sopenharmony_ci and :c:member:`~PyTypeObject.tp_clear` fields if the type inherits from a 547db96d56Sopenharmony_ci class that implements the garbage collector protocol and the child class 557db96d56Sopenharmony_ci does *not* include the :const:`Py_TPFLAGS_HAVE_GC` flag. 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci.. c:function:: TYPE* PyObject_GC_New(TYPE, PyTypeObject *type) 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci Analogous to :c:func:`PyObject_New` but for container objects with the 607db96d56Sopenharmony_ci :const:`Py_TPFLAGS_HAVE_GC` flag set. 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci.. c:function:: TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci Analogous to :c:func:`PyObject_NewVar` but for container objects with the 667db96d56Sopenharmony_ci :const:`Py_TPFLAGS_HAVE_GC` flag set. 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci.. c:function:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize) 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci Resize an object allocated by :c:func:`PyObject_NewVar`. Returns the 727db96d56Sopenharmony_ci resized object or ``NULL`` on failure. *op* must not be tracked by the collector yet. 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci.. c:function:: void PyObject_GC_Track(PyObject *op) 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci Adds the object *op* to the set of container objects tracked by the 787db96d56Sopenharmony_ci collector. The collector can run at unexpected times so objects must be 797db96d56Sopenharmony_ci valid while being tracked. This should be called once all the fields 807db96d56Sopenharmony_ci followed by the :c:member:`~PyTypeObject.tp_traverse` handler become valid, usually near the 817db96d56Sopenharmony_ci end of the constructor. 827db96d56Sopenharmony_ci 837db96d56Sopenharmony_ci 847db96d56Sopenharmony_ci.. c:function:: int PyObject_IS_GC(PyObject *obj) 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci Returns non-zero if the object implements the garbage collector protocol, 877db96d56Sopenharmony_ci otherwise returns 0. 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci The object cannot be tracked by the garbage collector if this function returns 0. 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_ci.. c:function:: int PyObject_GC_IsTracked(PyObject *op) 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci Returns 1 if the object type of *op* implements the GC protocol and *op* is being 957db96d56Sopenharmony_ci currently tracked by the garbage collector and 0 otherwise. 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci This is analogous to the Python function :func:`gc.is_tracked`. 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_ci .. versionadded:: 3.9 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ci 1027db96d56Sopenharmony_ci.. c:function:: int PyObject_GC_IsFinalized(PyObject *op) 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_ci Returns 1 if the object type of *op* implements the GC protocol and *op* has been 1057db96d56Sopenharmony_ci already finalized by the garbage collector and 0 otherwise. 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_ci This is analogous to the Python function :func:`gc.is_finalized`. 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ci .. versionadded:: 3.9 1107db96d56Sopenharmony_ci 1117db96d56Sopenharmony_ci 1127db96d56Sopenharmony_ci.. c:function:: void PyObject_GC_Del(void *op) 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ci Releases memory allocated to an object using :c:func:`PyObject_GC_New` or 1157db96d56Sopenharmony_ci :c:func:`PyObject_GC_NewVar`. 1167db96d56Sopenharmony_ci 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ci.. c:function:: void PyObject_GC_UnTrack(void *op) 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ci Remove the object *op* from the set of container objects tracked by the 1217db96d56Sopenharmony_ci collector. Note that :c:func:`PyObject_GC_Track` can be called again on 1227db96d56Sopenharmony_ci this object to add it back to the set of tracked objects. The deallocator 1237db96d56Sopenharmony_ci (:c:member:`~PyTypeObject.tp_dealloc` handler) should call this for the object before any of 1247db96d56Sopenharmony_ci the fields used by the :c:member:`~PyTypeObject.tp_traverse` handler become invalid. 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_ci.. versionchanged:: 3.8 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci The :c:func:`_PyObject_GC_TRACK` and :c:func:`_PyObject_GC_UNTRACK` macros 1307db96d56Sopenharmony_ci have been removed from the public C API. 1317db96d56Sopenharmony_ci 1327db96d56Sopenharmony_ciThe :c:member:`~PyTypeObject.tp_traverse` handler accepts a function parameter of this type: 1337db96d56Sopenharmony_ci 1347db96d56Sopenharmony_ci 1357db96d56Sopenharmony_ci.. c:type:: int (*visitproc)(PyObject *object, void *arg) 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci Type of the visitor function passed to the :c:member:`~PyTypeObject.tp_traverse` handler. 1387db96d56Sopenharmony_ci The function should be called with an object to traverse as *object* and 1397db96d56Sopenharmony_ci the third parameter to the :c:member:`~PyTypeObject.tp_traverse` handler as *arg*. The 1407db96d56Sopenharmony_ci Python core uses several visitor functions to implement cyclic garbage 1417db96d56Sopenharmony_ci detection; it's not expected that users will need to write their own 1427db96d56Sopenharmony_ci visitor functions. 1437db96d56Sopenharmony_ci 1447db96d56Sopenharmony_ciThe :c:member:`~PyTypeObject.tp_traverse` handler must have the following type: 1457db96d56Sopenharmony_ci 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ci.. c:type:: int (*traverseproc)(PyObject *self, visitproc visit, void *arg) 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci Traversal function for a container object. Implementations must call the 1507db96d56Sopenharmony_ci *visit* function for each object directly contained by *self*, with the 1517db96d56Sopenharmony_ci parameters to *visit* being the contained object and the *arg* value passed 1527db96d56Sopenharmony_ci to the handler. The *visit* function must not be called with a ``NULL`` 1537db96d56Sopenharmony_ci object argument. If *visit* returns a non-zero value that value should be 1547db96d56Sopenharmony_ci returned immediately. 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ciTo simplify writing :c:member:`~PyTypeObject.tp_traverse` handlers, a :c:func:`Py_VISIT` macro is 1577db96d56Sopenharmony_ciprovided. In order to use this macro, the :c:member:`~PyTypeObject.tp_traverse` implementation 1587db96d56Sopenharmony_cimust name its arguments exactly *visit* and *arg*: 1597db96d56Sopenharmony_ci 1607db96d56Sopenharmony_ci 1617db96d56Sopenharmony_ci.. c:function:: void Py_VISIT(PyObject *o) 1627db96d56Sopenharmony_ci 1637db96d56Sopenharmony_ci If *o* is not ``NULL``, call the *visit* callback, with arguments *o* 1647db96d56Sopenharmony_ci and *arg*. If *visit* returns a non-zero value, then return it. 1657db96d56Sopenharmony_ci Using this macro, :c:member:`~PyTypeObject.tp_traverse` handlers 1667db96d56Sopenharmony_ci look like:: 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_ci static int 1697db96d56Sopenharmony_ci my_traverse(Noddy *self, visitproc visit, void *arg) 1707db96d56Sopenharmony_ci { 1717db96d56Sopenharmony_ci Py_VISIT(self->foo); 1727db96d56Sopenharmony_ci Py_VISIT(self->bar); 1737db96d56Sopenharmony_ci return 0; 1747db96d56Sopenharmony_ci } 1757db96d56Sopenharmony_ci 1767db96d56Sopenharmony_ciThe :c:member:`~PyTypeObject.tp_clear` handler must be of the :c:type:`inquiry` type, or ``NULL`` 1777db96d56Sopenharmony_ciif the object is immutable. 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ci.. c:type:: int (*inquiry)(PyObject *self) 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_ci Drop references that may have created reference cycles. Immutable objects 1837db96d56Sopenharmony_ci do not have to define this method since they can never directly create 1847db96d56Sopenharmony_ci reference cycles. Note that the object must still be valid after calling 1857db96d56Sopenharmony_ci this method (don't just call :c:func:`Py_DECREF` on a reference). The 1867db96d56Sopenharmony_ci collector will call this method if it detects that this object is involved 1877db96d56Sopenharmony_ci in a reference cycle. 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_ci 1907db96d56Sopenharmony_ciControlling the Garbage Collector State 1917db96d56Sopenharmony_ci--------------------------------------- 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ciThe C-API provides the following functions for controlling 1947db96d56Sopenharmony_cigarbage collection runs. 1957db96d56Sopenharmony_ci 1967db96d56Sopenharmony_ci.. c:function:: Py_ssize_t PyGC_Collect(void) 1977db96d56Sopenharmony_ci 1987db96d56Sopenharmony_ci Perform a full garbage collection, if the garbage collector is enabled. 1997db96d56Sopenharmony_ci (Note that :func:`gc.collect` runs it unconditionally.) 2007db96d56Sopenharmony_ci 2017db96d56Sopenharmony_ci Returns the number of collected + unreachable objects which cannot 2027db96d56Sopenharmony_ci be collected. 2037db96d56Sopenharmony_ci If the garbage collector is disabled or already collecting, 2047db96d56Sopenharmony_ci returns ``0`` immediately. 2057db96d56Sopenharmony_ci Errors during garbage collection are passed to :data:`sys.unraisablehook`. 2067db96d56Sopenharmony_ci This function does not raise exceptions. 2077db96d56Sopenharmony_ci 2087db96d56Sopenharmony_ci 2097db96d56Sopenharmony_ci.. c:function:: int PyGC_Enable(void) 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ci Enable the garbage collector: similar to :func:`gc.enable`. 2127db96d56Sopenharmony_ci Returns the previous state, 0 for disabled and 1 for enabled. 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci .. versionadded:: 3.10 2157db96d56Sopenharmony_ci 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci.. c:function:: int PyGC_Disable(void) 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_ci Disable the garbage collector: similar to :func:`gc.disable`. 2207db96d56Sopenharmony_ci Returns the previous state, 0 for disabled and 1 for enabled. 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci .. versionadded:: 3.10 2237db96d56Sopenharmony_ci 2247db96d56Sopenharmony_ci 2257db96d56Sopenharmony_ci.. c:function:: int PyGC_IsEnabled(void) 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ci Query the state of the garbage collector: similar to :func:`gc.isenabled`. 2287db96d56Sopenharmony_ci Returns the current state, 0 for disabled and 1 for enabled. 2297db96d56Sopenharmony_ci 2307db96d56Sopenharmony_ci .. versionadded:: 3.10 231