Spec-Zone.ru › Python 3.13

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

Поддержка 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.

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)
Часть стабильного 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:

Py_VISIT(o)

Если PyObject* 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.

Получение сведений о состоянии сборщика мусора

C API предоставляет следующий интерфейс для получения сведений о сборщике мусора.

void PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg)
Это нестабильный API. Он может измениться без предупреждения в промежуточных выпусках.

Вызывает переданную функцию callback для всех живых объектов, поддерживающих GC. Параметр arg передаётся при каждом вызове callback.

Предупреждение

Если функция обратного вызова выделяет или освобождает новые объекты, поведение в отношении их посещения не определено.

Во время выполнения операции сборка мусора отключена. Явный запуск сборки мусора в функции обратного вызова может привести к неопределённому поведению, например к повторному посещению одних и тех же объектов или к тому, что они не будут посещены вовсе.

Добавлено в версии 3.12.

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

Тип функции-посетителя, передаваемой в PyUnstable_GC_VisitObjects(). arg совпадает с arg, переданным в PyUnstable_GC_VisitObjects. Возвращает 1 для продолжения итерации и 0 для её прекращения. Другие возвращаемые значения пока зарезервированы, поэтому поведение при возврате любого другого значения не определено.

Добавлено в версии 3.12.

© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/c-api/gcsupport.html

Spec-Zone.ru

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