Поддержка циклического сбора мусора
Поддержка Python для обнаружения и сбора мусора, связанного с циклическими ссылками, требует поддержки типов объектов, которые являются «контейнерами» для других объектов, которые также могут быть контейнерами. Типы, которые не хранят ссылки на другие объекты или которые хранят ссылки только на атомарные типы (например, числа или строки), не нуждаются в явной поддержке сбора мусора.
Для создания контейнерного типа поле tp_flags объекта типа должно включать Py_TPFLAGS_HAVE_GC и предоставить реализацию обработчика tp_traverse. Если экземпляры типа изменяемы, также должна быть предоставлена реализация tp_clear.
-
Py_TPFLAGS_HAVE_GC -
Объекты с типом, у которого установлен этот флаг, должны соответствовать правилам, описанным здесь. Для удобства эти объекты будут называться объектами-контейнерами.
Конструкторы контейнерных типов должны соответствовать двум правилам:
- Память для объекта должна быть выделена с помощью
PyObject_GC_NewилиPyObject_GC_NewVar. - После инициализации всех полей, которые могут содержать ссылки на другие контейнеры, необходимо вызвать
PyObject_GC_Track().
Аналогично, процедура освобождения памяти для объекта должна соответствовать аналогичной паре правил:
- Перед тем, как поля, ссылающиеся на другие контейнеры, будут аннулированы, необходимо вызвать
PyObject_GC_UnTrack(). -
Память объекта должна быть освобождена с помощью
PyObject_GC_Del().Предупреждение
Если тип добавляет Py_TPFLAGS_HAVE_GC, то он обязан реализовать хотя бы обработчик
tp_traverseили явно использовать обработчик из своего подкласса или подклассов.При вызове
PyType_Ready()или некоторых API, которые косвенно его вызывают, таких какPyType_FromSpecWithBases()илиPyType_FromSpec(), интерпретатор автоматически заполнит поляtp_flags,tp_traverseиtp_clear, если тип наследуется от класса, который реализует протокол сборки мусора, и дочерний класс не включает флагPy_TPFLAGS_HAVE_GC.
-
PyObject_GC_New(TYPE, typeobj) -
Аналогично
PyObject_New, но для объектов-контейнеров с установленным флагомPy_TPFLAGS_HAVE_GC.
-
PyObject_GC_NewVar(TYPE, typeobj, size) -
Аналогично
PyObject_NewVar, но для объектов-контейнеров с установленным флагомPy_TPFLAGS_HAVE_GC.
-
TYPE *PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize) -
Изменение размера объекта, выделенного с помощью
PyObject_NewVar. Возвращает измененный объект илиNULLв случае ошибки. op пока не отслеживается сборщиком.
-
void PyObject_GC_Track(PyObject *op) -
Часть Стабильной ABI.
Добавляет объект op в набор объектов-контейнеров, отслеживаемых сборщиком. Сборщик может запускаться в неожиданные моменты, поэтому объекты должны быть валидны во время отслеживания. Это должно вызываться после того, как все поля, за которым следует обработчик
tp_traverse, станут валидными, обычно в конце конструктора.
-
int PyObject_IS_GC(PyObject *obj) -
Возвращает ненулевое значение, если объект реализует протокол сборщика мусора, иначе возвращает 0.
Объект не может быть отслеживаем сборщиком мусора, если эта функция возвращает 0.
-
int PyObject_GC_IsTracked(PyObject *op) -
Часть Стабильной ABI с версии 3.9.
Возвращает 1, если тип объекта op реализует протокол GC и op в настоящее время отслеживается сборщиком мусора, и 0 в противном случае.
Аналогично Python-функции
gc.is_tracked().Добавлена в версии 3.9.
-
int PyObject_GC_IsFinalized(PyObject *op) -
Часть Стабильной ABI с версии 3.9.
Возвращает 1, если тип объекта op реализует протокол GC и op уже был завершен сборщиком мусора, и 0 в противном случае.
Аналогично Python-функции
gc.is_finalized().Добавлена в версии 3.9.
-
void PyObject_GC_Del(void *op) -
Часть Стабильной ABI.
Освобождает память, выделенную объекту с помощью
PyObject_GC_NewилиPyObject_GC_NewVar.
-
void PyObject_GC_UnTrack(void *op) -
Часть Стабильной ABI.
Удаляет объект op из набора объектов-контейнеров, отслеживаемых сборщиком. Обратите внимание, что
PyObject_GC_Track()может быть вызван снова для этого объекта, чтобы добавить его обратно в набор отслеживаемых объектов. Функция освобождения памяти (tp_deallocобработчик) должна вызвать это для объекта перед тем, как любые поля, используемые обработчикомtp_traverse, станут недействительными.
Изменено в версии 3.8: Макросы _PyObject_GC_TRACK() и _PyObject_GC_UNTRACK() были удалены из публичного C API.
Обработчик tp_traverse принимает в качестве параметра функцию этого типа:
-
typedef int (*visitproc)(PyObject *object, void *arg) -
Часть Стабильной ABI.
Тип функции-посетителя, передаваемой обработчику
tp_traverse. Функция должна вызываться с объектом для обхода в качестве object и третьим параметром обработчикаtp_traverseкак arg. Ядро Python использует несколько функций-посетителей для реализации обнаружения циклического мусора; не ожидается, что пользователям потребуется писать свои собственные функции-посетители.
Обработчик tp_traverse должен иметь следующий тип:
-
typedef int (*traverseproc)(PyObject *self, visitproc visit, void *arg) -
Часть Стабильной ABI.
Функция обхода для объекта-контейнера. Реализации должны вызывать функцию visit для каждого объекта, непосредственно содержащегося в self, при этом параметрами visit являются содержащийся объект и значение arg, переданное обработчику. Функция visit не должна вызываться с аргументом объекта
NULL. Если visit возвращает ненулевое значение, это значение должно быть возвращено немедленно.
Для упрощения написания обработчиков tp_traverse, предоставляется макрос Py_VISIT(). Для использования этого макроса, реализация tp_traverse должна именовать свои аргументы точно как visit и arg:
-
void Py_VISIT(PyObject *o) -
Если o не
NULL, вызовите обратный вызов visit с аргументами o и arg. Если visit возвращает ненулевое значение, верните его. Используя этот макрос, обработчикиtp_traverseвыглядят так:static int my_traverse(Noddy *self, visitproc visit, void *arg) { Py_VISIT(self->foo); Py_VISIT(self->bar); return 0; }
Обработчик tp_clear должен быть типа inquiry, или NULL если объект неизменяемый.
-
typedef int (*inquiry)(PyObject *self) -
Часть Стабильной ABI.
Освободите ссылки, которые могли создать циклы ссылок. Неизменяемые объекты не обязаны определять этот метод, так как они никогда не могут напрямую создавать циклы ссылок. Обратите внимание, что объект должен оставаться корректным после вызова этого метода (не просто вызывайте
Py_DECREF()на ссылке). Коллектор вызовет этот метод, если обнаружит, что этот объект участвует в цикле ссылок.
Управление состоянием сборщика мусора
C-API предоставляет следующие функции для управления запусками сборки мусора.
-
Py_ssize_t PyGC_Collect(void) -
Часть Стабильной ABI.
Выполните полную сборку мусора, если сборщик мусора включён. (Обратите внимание, что
gc.collect()запускает его безусловно.)Возвращает количество собранных + недоступных объектов, которые нельзя собрать. Если сборщик мусора отключён или уже собирает, возвращает
0сразу. Ошибки при сборке мусора передаются вsys.unraisablehook. Эта функция не вызывает исключения.
-
int PyGC_Enable(void) -
Часть Стабильной ABI с версии 3.10.
Включить сборщик мусора: аналогично
gc.enable(). Возвращает предыдущее состояние, 0 для выключенного и 1 для включённого.Новое в версии 3.10.
-
int PyGC_Disable(void) -
Часть Стабильной ABI с версии 3.10.
Отключить сборщик мусора: аналогично
gc.disable(). Возвращает предыдущее состояние, 0 для выключенного и 1 для включённого.Новое в версии 3.10.
-
int PyGC_IsEnabled(void) -
Часть Стабильной ABI с версии 3.10.
Запрос состояния сборщика мусора: аналогично
gc.isenabled(). Возвращает текущее состояние, 0 для выключенного и 1 для включённого.Новое в версии 3.10.
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/c-api/gcsupport.html