Spec-Zone.ru › Python 3.12

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

Поддержка 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() удалены из общедоступного 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() для ссылки). Сборщик вызовет этот метод, если обнаружит, что объект участвует в цикле ссылок.

Управление состоянием сборщика мусора

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

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.

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

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

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. Возвращает 0, чтобы продолжить итерацию, и 1, чтобы остановить её. Другие возвращаемые значения пока зарезервированы, поэтому поведение при возврате любого другого значения не определено.

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

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

Spec-Zone.ru

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