Содержание страницы
Поддержка циклической сборки мусора¶Supporting Cyclic Garbage Collection
Поддержка 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)¶
- Часть Stable ABI.
Добавляет объект op в набор контейнерных объектов, отслеживаемых сборщиком. Сборщик может запускаться в неожиданные моменты, поэтому объекты должны быть корректны во время отслеживания. Эту функцию следует вызывать, когда все поля, за которыми следит обработчик
tp_traverse, станут корректны, обычно ближе к концу конструктора.
-
int PyObject_IS_GC(PyObject *obj)¶
Возвращает ненулевое значение, если объект реализует протокол сборщика мусора, иначе возвращает 0.
Объект не может отслеживаться сборщиком мусора, если эта функция возвращает 0.
-
int PyObject_GC_IsTracked(PyObject *op)¶
- Часть Stable ABI начиная с версии 3.9.
Возвращает 1, если тип объекта op реализует протокол GC и op в данный момент отслеживается сборщиком мусора, и 0 в противном случае.
Это аналог функции Python
gc.is_tracked().Добавлено в версии 3.9.
-
int PyObject_GC_IsFinalized(PyObject *op)¶
- Часть Stable ABI начиная с версии 3.9.
Возвращает 1, если тип объекта op реализует протокол GC и op уже был финализирован сборщиком мусора, и 0 в противном случае.
Это аналог функции Python
gc.is_finalized().Добавлено в версии 3.9.
-
void PyObject_GC_Del(void *op)¶
- Часть Stable ABI.
Освобождает память, выделенную объекту через
PyObject_GC_NewилиPyObject_GC_NewVar.
-
void PyObject_GC_UnTrack(void *op)¶
- Часть Stable 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)¶
- Часть Stable ABI.
Тип функции обхода, передаваемой обработчику
tp_traverse. Функцию следует вызывать с объектом для обхода в качестве object и третьим параметром обработчикаtp_traverseв качестве arg. Ядро Python использует несколько функций обхода для реализации обнаружения циклического мусора; не ожидается, что пользователям потребуется писать собственные функции обхода.
Обработчик tp_traverse должен иметь следующий тип:
-
typedef int (*traverseproc)(PyObject *self, visitproc visit, void *arg)¶
- Часть Stable ABI.
Функция обхода для объекта-контейнера. Реализации должны вызывать функцию visit для каждого объекта, непосредственно содержащегося в self; параметрами visit являются содержащийся объект и значение arg, переданное обработчику. Функция visit не должна вызываться с аргументом-объектом
NULL. Если visit возвращает ненулевое значение, его следует немедленно вернуть.Функция обхода не должна иметь побочных эффектов. Реализации не должны изменять счётчики ссылок каких-либо объектов Python, а также создавать или уничтожать объекты Python.
Чтобы упростить написание обработчиков 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)¶
- Часть Stable ABI.
Удаляет ссылки, которые могли создать циклические ссылки. Неизменяемые объекты не обязаны определять этот метод, поскольку они никогда не могут напрямую создавать циклические ссылки. Обратите внимание, что объект после вызова этого метода должен оставаться корректным (нельзя просто вызвать
Py_DECREF()для ссылки). Сборщик вызовет этот метод, если обнаружит, что этот объект участвует в циклической ссылке.
Управление состоянием сборщика мусора¶Controlling the Garbage Collector State
C-API предоставляет следующие функции для управления запусками сборки мусора.
-
Py_ssize_t PyGC_Collect(void)¶
- Часть Stable ABI.
Выполняет полную сборку мусора, если сборщик мусора включён. (Обратите внимание, что
gc.collect()запускает её безусловно.)Возвращает количество собранных + недостижимых объектов, которые не могут быть собраны. Если сборщик мусора отключён или уже выполняет сборку, немедленно возвращает
0. Ошибки во время сборки мусора передаются вsys.unraisablehook. Эта функция не вызывает исключений.
-
int PyGC_Enable(void)¶
- Часть Stable ABI начиная с версии 3.10.
Включает сборщик мусора: аналогично
gc.enable(). Возвращает предыдущее состояние: 0 – отключён, 1 – включён.Добавлено в версии 3.10.
-
int PyGC_Disable(void)¶
- Часть Stable ABI начиная с версии 3.10.
Отключает сборщик мусора: аналогично
gc.disable(). Возвращает предыдущее состояние: 0 – отключён, 1 – включён.Добавлено в версии 3.10.
-
int PyGC_IsEnabled(void)¶
- Часть Stable ABI начиная с версии 3.10.
Запрашивает состояние сборщика мусора: аналогично
gc.isenabled(). Возвращает текущее состояние: 0 – отключён, 1 – включён.Добавлено в версии 3.10.
Запрос состояния сборщика мусора¶Querying Garbage Collector State
C-API предоставляет следующий интерфейс для запроса информации о сборщике мусора.
-
void PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg)¶
- Это нестабильное API. Оно может меняться без предупреждения в минорных версиях.
Вызывает переданный колбэк для всех живых объектов, поддерживающих GC. arg передаётся во все вызовы колбэк.
Предупреждение
Если колбэк выделяет или освобождает новые объекты, то не определено, будут ли они посещены.
Во время работы сборка мусора отключена. Явный запуск сборки в колбэке может привести к неопределённому поведению, например, к посещению одних и тех же объектов несколько раз или ни разу.
Добавлено в версии 3.12.
-
typedef int (*gcvisitobjects_t)(PyObject *object, void *arg)¶
Тип функции-посетителя, передаваемой в
PyUnstable_GC_VisitObjects(). Параметр arg – то же самое, что arg, переданный вPyUnstable_GC_VisitObjects. Возвращайте1для продолжения итерации,0– для остановки. Остальные возвращаемые значения пока зарезервированы, поэтому поведение при возврате чего-либо другого не определено.Добавлено в версии 3.12.