GC и самоссылка списка в Python

GC и самоссылка списка в Python

@python_quiz

Разберем этот квиз

Коротко — код создает список, который содержит сам себя, и проверяет, отслеживается ли он сборщиком циклов. Ответ — объект будет отслеживаться, поэтому функция проверки вернет True. Ниже разберём почему и разберём варианты ответов.

Условие (код)

python

Этот код:

  • создает пустой список x = []
  • добавляет в него саму ссылку на x (самоссылка)
  • печатает результат gc.is_tracked(x)

Почему возвращается True

Короткое объяснение:

  • CPython использует подсчет ссылок (reference counting) для немедленной очистки большинства объектов и дополняет это поколенческим сборщиком циклов (gc) для поиска и удаления объектов, связанных циклическими ссылками.
  • Самоссылка (когда структура данных содержит ссылку на саму себя) образует цикл ссылок. Такие объекты не могут быть очищены только счётчиком ссылок — нужен сборщик циклов.
  • gc.is_tracked(obj) возвращает True, если объект находится под наблюдением сборщика циклов. Поскольку список с самоссылкой потенциально участвует в цикле, он будет отслеживаться — поэтому ожидаемый вывод True.

Дополнительно, если вы вывели бы сам список, он будет показан в особой форме, обозначающей рекурсию:

python

Демонстрация (пример кода)

python

Можно также убедиться, что сборщик циклов справляется с циклами:

python

(Заметьте: gc.collect возвращает число собранных объектов; детали зависят от конкретного окружения и версии CPython.)

Разбор вариантов ответов

  • "Выведет False, список без циклических ссылок не отслеживается"

Неверно в контексте данного кода: список содержит самоссылку — это цикл, и объект будет отслеживаться. Кроме того, многие контейнеры по умолчанию могут отслеживаться сборщиком циклов.

  • "Выведет True, список с циклической ссылкой отслеживается GC"

Это корректное объяснение ситуации: самоссылка делает список кандидатом для обнаружения циклов, и gc.is_tracked возвращает True.

  • "Выведет ошибку из-за самоссылки списка"

Неверно: Python нормально поддерживает самоссылки. При попытке вывести такой список выводится рекурсивное представление вроде [[...]], но никакой ошибки не возникает.

  • "Выведет случайное значение, зависящее от версии Python"

Неверно в практическом смысле: поведение детерминировано реализацией сборщика в конкретной реализации Python (в CPython — описанное поведение). Различия между реализациями (например, PyPy, Jython) возможны, но в практике CPython результат будет определён — True.

Дополнительные замечания

  • gc.is_tracked отражает текущее состояние отслеживания объектом сборщика циклов в конкретной реализации CPython. Это не свойство самого объекта в абстрактном смысле языка Python, а характеристика реализации.
  • Наличие метода __del__ у объектов, участвующих в цикле, может осложнить автоматическую уборку таких циклов: сборщик не всегда может безопасно удалить объекты с финализаторами, и они могут остаться в gc.garbage.
  • Поведение отображения самоссылки (например [[...]]) — полезная диагностика при отладке рекурсивных структур.

Вывод

Самоссылка делает список участником циклических ссылок, и в CPython такой объект отслеживается сборщиком циклов. В рассматриваемом фрагменте gc.is_tracked(x) вернёт True; никакой ошибки не произойдет, а представление списка при печати визуально укажет на рекурсию.

Report Page