Поддержка циклического сбора мусора
Поддержка 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.
-
PyObject *PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *type, size_t extra_size) -
Это Нестабильный API. Он может быть изменен без предупреждения в незначительных релизах.
Аналогично
PyObject_GC_New, но выделяет extra_size байтов в конце объекта (по смещениюtp_basicsize). Выделенная память инициализируется нулями, за исключениемPython object header.Дополнительные данные будут освобождены вместе с объектом, но в остальном они не управляются Python.
Предупреждение
Функция помечена как нестабильная, потому что окончательный механизм резервирования дополнительных данных после создания экземпляра еще не определен. Для выделения переменного количества полей предпочтительнее использовать
PyVarObjectиtp_itemsize.Добавлен в версии 3.12.
-
PyObject_GC_Resize(TYPE, op, newsize) -
Изменение размера объекта, выделенного с помощью
PyObject_NewVar. Возвращает измененный объект типаTYPE*(ссылается на любой тип C) илиNULLпри ошибке.op должен быть типа PyVarObject* и пока не должен отслеживаться коллектором. newsize должен быть типа
Py_ssize_t.
-
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) -
Часть Стабильного API.
Тип функции-визитора, передаваемой обработчику
tp_traverse. Функция должна вызываться с объектом для обхода в качестве параметра object и третьим параметром обработчикаtp_traverseв качестве параметра arg. Ядро Python использует несколько функций-визиторов для реализации обнаружения циклических ссылок; не ожидается, что пользователям потребуется писать свои собственные функции-визиторы.
Обработчик tp_traverse должен иметь следующий тип:
-
typedef int (*traverseproc)(PyObject *self, visitproc visit, void *arg) -
Часть Стабильного API.
Функция обхода для контейнерного объекта. Реализации должны вызывать функцию 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) -
Часть Стабильного API.
Освободить ссылки, которые могут создать циклические ссылки. Неизменяемые объекты не должны определять этот метод, так как они никогда не могут непосредственно создавать циклические ссылки. Обратите внимание, что объект должен оставаться действительным после вызова этого метода (не просто вызывайте
Py_DECREF()на ссылке). Коллектор вызовет этот метод, если обнаружит, что этот объект участвует в циклической ссылке.
Управление состоянием сборщика мусора
C-API предоставляет следующие функции для управления запуском сборки мусора.
-
Py_ssize_t PyGC_Collect(void) -
Часть Стабильного API.
Выполнить полную сборку мусора, если сборщик мусора включен. (Обратите внимание, что
gc.collect()выполняет ее безусловно.)Возвращает количество собранных + недоступных объектов, которые нельзя собрать. Если сборщик мусора отключен или уже собирает, возвращает
0немедленно. Ошибки при сборе мусора передаются вsys.unraisablehook. Эта функция не вызывает исключений.
-
int PyGC_Enable(void) -
Часть Стабильного API с версии 3.10.
Включить сборщик мусора: аналогично
gc.enable(). Возвращает предыдущее состояние, 0 для отключенного и 1 для включенного.Добавлен в версии 3.10.
-
int PyGC_Disable(void) -
Часть Стабильного API с версии 3.10.
Отключить сборщик мусора: аналогично
gc.disable(). Возвращает предыдущее состояние, 0 для отключенного и 1 для включенного.Добавлен в версии 3.10.
-
int PyGC_IsEnabled(void) -
Часть Стабильного API с версии 3.10.
Запрос состояния сборщика мусора: аналогично
gc.isenabled(). Возвращает текущее состояние, 0 для отключенного и 1 для включенного.Добавлен в версии 3.10.
Запрос состояния сборщика мусора
C-API предоставляет следующий интерфейс для запроса информации о сборщике мусора.
-
void PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg) -
Это Нестабильный API. Может быть изменен без предупреждения в незначительных выпусках.
Выполнить предоставленный callback для всех активных объектов, поддерживающих сборку мусора. arg передаётся во все вызовы callback.
Предупреждение
Если новые объекты (де)аллоцируются обратным вызовом, не определено, будут ли они посещены.
Сборка мусора отключена во время работы. Явное выполнение сборки в обратном вызове может привести к неопределённому поведению, например, к посещению одних и тех же объектов несколько раз или вообще не посещению.
Добавлен в версии 3.12.
-
typedef int (*gcvisitobjects_t)(PyObject *object, void *arg) -
Тип функции-визитора, который необходимо передать в
PyUnstable_GC_VisitObjects(). arg — тот же arg, что и переданный вPyUnstable_GC_VisitObjects. Возвращайте0для продолжения итерации, возвращайте1для остановки итерации. Другие возвращаемые значения зарезервированы на данный момент, поэтому поведение при возвращении чего-либо другого не определено.Добавлен в версии 3.12.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/c-api/gcsupport.html