Spec-Zone.ru › Python 3.10

Поддержка циклического сбора мусора

Поддержка Python для обнаружения и сбора мусора, включающего циклические ссылки, требует поддержки типов объектов, которые являются «контейнерами» для других объектов, которые также могут быть контейнерами. Типы, которые не хранят ссылки на другие объекты или которые хранят ссылки только на атомарные типы (например, числа или строки), не нуждаются в предоставлении какой-либо явной поддержки для сбора мусора.

Для создания типа контейнера поле tp_flags объекта типа должно включать Py_TPFLAGS_HAVE_GC и предоставить реализацию обработчика tp_traverse. Если экземпляры типа изменяемы, также должна быть предоставлена реализация tp_clear.

Py_TPFLAGS_HAVE_GC

Объекты с типом, для которого установлен этот флаг, должны соответствовать правилам, описанным здесь. Для удобства эти объекты будут называться объектами-контейнерами.

Конструкторы для типов контейнеров должны соответствовать двум правилам:

  1. Память для объекта должна быть выделена с помощью PyObject_GC_New() или PyObject_GC_NewVar().
  2. После инициализации всех полей, которые могут содержать ссылки на другие контейнеры, необходимо вызвать PyObject_GC_Track().

Аналогично, процедура освобождения памяти для объекта должна соответствовать похожей паре правил:

  1. Перед тем, как поля, ссылающиеся на другие контейнеры, будут признаны недействительными, необходимо вызвать PyObject_GC_UnTrack().
  2. Память объекта должна быть освобождена с помощью 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.

TYPE *PyObject_GC_New(TYPE, PyTypeObject *type)

Аналогично PyObject_New(), но для объектов-контейнеров с установленным флагом Py_TPFLAGS_HAVE_GC.

TYPE *PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t 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() были удалены из публичного API C.

Обработчик 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.10/c-api/gcsupport.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API