Ответ
Python использует комбинацию двух механизмов для управления памятью: подсчёт ссылок (reference counting) и циклический сборщик мусора (generational garbage collector).
-
Подсчёт ссылок: Основной и самый быстрый механизм. У каждого объекта есть счётчик. Когда на объект создаётся новая ссылка, счётчик увеличивается. Когда ссылка удаляется, счётчик уменьшается. Как только счётчик достигает нуля, объект немедленно удаляется.
-
Проблема: Подсчёт ссылок не работает для циклических зависимостей. В этом случае счётчики ссылок объектов в цикле никогда не достигнут нуля, даже если на них нет внешних ссылок. Это приводит к утечке памяти.
# Создание циклической ссылки a = [] b = [] a.append(b) b.append(a) # Удаляем внешние ссылки на a и b del a del b # Объекты-списки все еще ссылаются друг на друга, # их счетчики ссылок равны 1. Память не освобождается. -
Решение: Для обнаружения и очистки таких циклов в Python есть generational garbage collector. Он периодически запускается и ищет группы объектов, на которые можно сослаться только изнутри этих же групп. Найдя такой "остров" недостижимых объектов, он их удаляет.
Для ручного управления можно использовать модуль gc или слабые ссылки weakref:
- Принудительный запуск сборщика:
import gc; gc.collect() - Слабые ссылки: Модуль
weakrefпозволяет создавать ссылки на объекты, которые не увеличивают их счётчик ссылок, тем самым предотвращая образование циклов.