O coletor de lixo e referências cíclicas
Aprenda como o módulo gc lida com ciclos de referências.
O coletor de lixo e referências cíclicas é uma aula grátis de Python Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Python Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Python Academy inclui 4 aulas no total.
Por que a contagem de referências não é suficiente
A contagem de referências não consegue coletar objetos envolvidos em ciclos de referências — cada um mantém uma referência para o outro, portanto nenhuma das contagens chega a 0.
# Reference cycle: a → b → a
a = {}
b = {"other": a}
a["other"] = b
del a, b
# Both objects are unreachable but refcount > 0
# Only the cyclic GC can collect themO módulo gc
gc é o coletor de lixo cíclico. Periodicamente, ele verifica os objetos monitorados em busca de ciclos inacessíveis e os coleta.
import gc
gc.collect() # trigger immediately
print(gc.garbage) # objects with __del__ in cycles (cannot auto-collect)Coleta geracional
O GC utiliza três gerações. Objetos novos começam na geração 0. Os objetos que sobrevivem a uma coleta são promovidos. A geração 0 é coletada com mais frequência.
import gc
print(gc.get_count()) # (gen0, gen1, gen2) allocations since last collection
print(gc.get_threshold()) # (700, 10, 10) — thresholds for each generation
gc.set_threshold(1000, 15, 10) # tuneDetecção de ciclos com gc.get_referents
Inspecione a quais objetos um objeto faz referência — isso é útil para entender por que algo não está sendo coletado.
import gc
a = []
b = [a]
a.append(b)
for ref in gc.get_referents(a):
print(ref) # shows bgc.get_objects()
gc.get_objects() retorna todos os objetos atualmente monitorados pelo GC. É útil para encontrar vazamentos de memória.
import gc
before = len(gc.get_objects())
create_lots_of_objects()
after = len(gc.get_objects())
print(f"Leaked: {after - before} objects")Como evitar ciclos
Projete estruturas de dados para evitar ciclos: utilize weakrefs para referências inversas, utilize IDs em vez de referências diretas ou desfaça os ciclos explicitamente antes que os objetos saiam do escopo.
import weakref
class Node:
def __init__(self, parent):
# weakref avoids cycle:
self.parent = weakref.ref(parent)
class Tree:
def __init__(self):
self.child = Node(self) # no hard cycle__del__ e ciclos
Objetos com __del__ envolvidos em um ciclo não podem ser coletados automaticamente. Em vez disso, eles são colocados em gc.garbage.
import gc
class Leaky:
def __del__(self): pass
a = Leaky()
b = Leaky()
a.other = b
b.other = a
del a, b
gc.collect()
print(gc.garbage) # [Leaky, Leaky] — cannot collectgc.freeze() — Python 3.7 ou posterior
gc.freeze() congela os objetos atualmente monitorados, para que nunca sejam coletados. Isso é útil em processos de longa duração após a inicialização, pois reduz as pausas do GC.
import gc
# After all globals and imports are in place:
gc.freeze() # no GC scanning for these objects ever again
# Useful for: gunicorn pre-fork, background serversDesativação e reativação do GC
Desative o GC cíclico em loops compactos nos quais você sabe que não existem ciclos; depois, reative-o e force uma coleta.
import gc
gc.disable()
try:
result = tight_loop_no_cycles()
finally:
gc.enable()
gc.collect()isenabled e isfinalized
Verifique o estado do GC com gc.isenabled() e detecte se um objeto está sendo finalizado com gc.is_finalized(obj).
import gc
print(gc.isenabled()) # True by default
obj = object()
print(gc.is_finalized(obj)) # False (still alive)Padrões de vazamento de memória
Causas comuns de vazamentos de memória em Python: caches globais que crescem sem limite, ouvintes de eventos que não são desconectados, referências cíclicas com __del__ e extensões C que vazam referências.
# Typical leaks:
global_cache = {} # grows forever — use lru_cache with maxsize
class EventBus:
listeners = []
# Listeners hold references to objects:
# @classmethod
# def on(cls, fn): cls.listeners.append(fn)
# Must call off() to detachVerificação rápida
O que acontece com objetos que têm __del__ e estão envolvidos em um ciclo de referências?
Recapitulação
O GC cíclico trata ciclos de referências que a contagem de referências não consegue tratar. Ele utiliza três gerações e promove os objetos sobreviventes. Evite ciclos com weakrefs. Objetos com __del__ em ciclos acabam em gc.garbage. Utilize gc.freeze() após a inicialização para reduzir as pausas do GC em servidores de longa duração.
Perguntas Frequentes
A aula “O coletor de lixo e referências cíclicas” é grátis?
Sim — o texto completo de “O coletor de lixo e referências cíclicas” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Python Academy, atualize para CoddyKit PRO. O curso de Python Academy inclui 4 aulas no total.
O que vou aprender em “O coletor de lixo e referências cíclicas”?
Aprenda como o módulo gc lida com ciclos de referências. Você pratica Python Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Python Academy?
Nenhuma experiência prévia é necessária. Python Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “O coletor de lixo e referências cíclicas”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Python Academy?
Sim. Cada aula de Python Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Contagem de referências do CPython
- O coletor de lixo e referências cíclicas
- Criação de perfis com cProfile e line_profiler
- Criação de perfis de memória com tracemalloc