Ответ
В Python используется сборщик мусора на основе подсчета ссылок с дополнительным циклическим сборщиком для обнаружения недостижимых объектов.
Основной механизм (подсчет ссылок):
- Каждый объект имеет счетчик ссылок.
- При создании новой ссылки счетчик увеличивается, при удалении — уменьшается.
- Когда счетчик достигает нуля, память объекта немедленно освобождается.
Циклический сборщик (Generational GC):
- Обнаруживает и удаляет циклические ссылки (когда объекты ссылаются друг на друга, но недоступны извне).
- Использует поколения (0, 1, 2). Новые объекты попадают в поколение 0.
- Чаще проверяет молодые поколения, реже — старые.
Пример цикла:
class Node:
def __init__(self):
self.ref = None
# Создание циклической ссылки
a = Node()
b = Node()
a.ref = b
b.ref = a
# Удаляем внешние ссылки
a = None
b = None
# Теперь объекты недостижимы, но счетчики ссылок не нулевые.
# Их удалит циклический сборщик.
Управление GC:
gc.enable()/gc.disable()— включить/выключить.gc.collect()— принудительный запуск.gc.get_threshold()— пороги для поколений.
Ответ 18+ 🔞
Да ты посмотри, какая красота, блядь! В Питоне-то, оказывается, мусор выносят по-умному, а не как у нас в подъезде. Сидит себе тихо сборщик на подсчёте ссылок, как бухгалтер в конторе.
Вот как он, сука, работает (основной механизм):
- У каждого объекта, будь то список, словарь или твоя кривая функция, есть свой личный счётчик, блядь.
- Как только на него кто-то начинает показывать пальцем (создаётся ссылка) — счётчик плюсует. Отвёл взгляд (удалил ссылку) — минусует.
- И вот когда этот счётчик падает до нуля — тут же, нахуй, объект в утиль! Память чиста. Красота, ёпта.
Но есть же, блядь, и подлянка — циклические ссылки! Вот тут вступает циклический сборщик (Generational GC), этакий спецназ по зачистке говна.
- Его задача — находить эти вот пиздецовые круговые поручительства, когда два объекта друг за друга держатся, но весь остальной мир про них уже забыл. Мёртвый хват, блядь.
- Работает он по поколениям (0, 1, 2). Всё новое и горячее — в поколение 0, как молодые пиздюки. Их проверяют часто-часто. А то, что выжило после нескольких чисток, переходит в поколения постарше, и их уже тревожат реже. Логично же, ебать мои старые костыли.
Смотри, какой наглядный пиздец:
class Node:
def __init__(self):
self.ref = None
# Создаём циклическую ссылку — классика жанра!
a = Node()
b = Node()
a.ref = b
b.ref = a # Всё, они поженились, блядь.
# А теперь внешний мир о них забывает
a = None
b = None
# И сидят теперь два этих чудака, держатся за ручки, счётчики у них по 1, но они уже никому не нужны!
# Вот тут наш циклический сборщик и придёт, как санитар леса, и разъебёт этот порочный круг.
Ну и если совсем припёрло, можно им порулить:
gc.enable()/gc.disable()— включить или вырубить этого санитара нахуй.gc.collect()— орать на него "Давай, работай, блядь, сейчас же!" для принудительной зачистки.gc.get_threshold()— посмотреть, через сколько пинков он начинает проверять каждое поколение.