El recolector de basura y las referencias cíclicas
Aprenda cómo el módulo gc gestiona los ciclos de referencias.
El recolector de basura y las referencias cíclicas es una lección gratuita de Python Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Python Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Python Academy incluye 4 lecciones en total.
Por qué no basta el conteo de referencias
El conteo de referencias no puede recopilar los objetos que participan en ciclos de referencias: cada uno mantiene una referencia al otro, por lo que ninguno de los contadores llega 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 themEl módulo gc
gc es el recolector de basura cíclico. Explora periódicamente los objetos rastreados en busca de ciclos inaccesibles y los recopila.
import gc
gc.collect() # trigger immediately
print(gc.garbage) # objects with __del__ in cycles (cannot auto-collect)Recolección generacional
El GC utiliza tres generaciones. Los objetos nuevos comienzan en la generación 0. Los objetos que sobreviven a una recolección ascienden de generación. La generación 0 se recolecta con mayor frecuencia.
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) # tuneDetección de ciclos con gc.get_referents
Inspeccione a qué objetos hace referencia un objeto; es útil para entender por qué algo no se está recopilando.
import gc
a = []
b = [a]
a.append(b)
for ref in gc.get_referents(a):
print(ref) # shows bgc.get_objects()
gc.get_objects() devuelve todos los objetos rastreados actualmente por el GC. Es útil para encontrar fugas de memoria.
import gc
before = len(gc.get_objects())
create_lots_of_objects()
after = len(gc.get_objects())
print(f"Leaked: {after - before} objects")Cómo evitar ciclos
Diseñe estructuras de datos que eviten los ciclos: use weakrefs para las referencias inversas, use identificadores en lugar de referencias directas o rompa los ciclos explícitamente antes de que los objetos salgan de ámbito.
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__ y los ciclos
Los objetos con __del__ que participan en un ciclo no pueden recopilarse automáticamente. En su lugar, se colocan en 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+
gc.freeze() congela los objetos rastreados actualmente para que nunca se recopilen. Es útil en procesos de larga duración después del inicio para reducir las pausas del 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 serversDeshabilitación y reactivación del GC
Deshabilite el GC cíclico en bucles cerrados cuando sepa que no existen ciclos y, después, vuelva a habilitarlo y fuerce una recolección.
import gc
gc.disable()
try:
result = tight_loop_no_cycles()
finally:
gc.enable()
gc.collect()isenabled e isfinalized
Compruebe el estado del GC con gc.isenabled() y detecte si un objeto se está finalizando con gc.is_finalized(obj).
import gc
print(gc.isenabled()) # True by default
obj = object()
print(gc.is_finalized(obj)) # False (still alive)Patrones de fugas de memoria
Causas comunes de fugas de memoria en Python: cachés globales que crecen sin límites, listeners de eventos que no se desconectan, referencias cíclicas con __del__ y extensiones de C que pierden referencias.
# 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 detachComprobación rápida
¿Qué ocurre con los objetos que tienen __del__ y participan en un ciclo de referencias?
Recapitulación
El GC cíclico gestiona los ciclos de referencias que el conteo de referencias no puede recopilar. Utiliza tres generaciones y asciende de generación a los objetos supervivientes. Evite los ciclos mediante weakrefs. Los objetos con __del__ que forman parte de ciclos terminan en gc.garbage. Use gc.freeze() después del inicio para reducir las pausas del GC en servidores de larga duración.
Preguntas frecuentes
¿La lección «El recolector de basura y las referencias cíclicas» es gratis?
Sí — el texto completo de «El recolector de basura y las referencias cíclicas» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Python Academy, actualiza a CoddyKit PRO. El curso de Python Academy incluye 4 lecciones en total.
¿Qué aprenderé en «El recolector de basura y las referencias cíclicas»?
Aprenda cómo el módulo gc gestiona los ciclos de referencias. Practicas Python Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Python Academy?
No se requiere experiencia previa. Python Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «El recolector de basura y las referencias cíclicas»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Python Academy?
Sí. Cada lección de Python Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Conteo de referencias en CPython
- El recolector de basura y las referencias cíclicas
- Perfilado con cProfile y line_profiler
- Perfilado de memoria con tracemalloc