Conteo de referencias en CPython
Comprenda cómo CPython controla la vida útil de los objetos mediante recuentos de referencias.
Conteo de referencias en CPython es una lección gratuita de Python Academy en CoddyKit. Esta es la lección 1 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.
¿Qué es el conteo de referencias?
CPython realiza un seguimiento del contador de referencias de cada objeto. Cuando el contador llega a 0, el objeto se desasigna inmediatamente. Este es el mecanismo principal de gestión de memoria de Python.
import sys
x = [1, 2, 3]
print(sys.getrefcount(x)) # 2 (x + getrefcount arg)
y = x
print(sys.getrefcount(x)) # 3sys.getrefcount()
sys.getrefcount(obj) devuelve el contador de referencias actual. Nota: llamarlo añade 1 (la referencia del argumento de la función).
import sys
a = "hello"
print(sys.getrefcount(a)) # baseline (may be high for interned strings)
b = a
print(sys.getrefcount(a)) # one more
del b
print(sys.getrefcount(a)) # back to baselineIncremento y decremento
Cada asignación incrementa el contador; cada eliminación o reasignación lo decrementa. Cuando el contador llega a 0, CPython llama al desasignador del objeto.
x = [] # refcount = 1
y = x # refcount = 2
z = [x] # refcount = 3 (list holds a reference)
del y # refcount = 2
z.clear() # refcount = 1
del x # refcount = 0 → deallocatedInternamiento de objetos
CPython interna los enteros pequeños (de -5 a 256) y muchos literales de cadena, reutilizando el mismo objeto. Las comparaciones con is permiten observarlo.
a = 256
b = 256
print(a is b) # True (interned)
c = 257
d = 257
print(c is d) # may be False (not interned)Referencias débiles
Las referencias débiles no incrementan el contador de referencias. Son útiles para evitar impedir la recolección de basura de objetos que quiere observar, pero no poseer.
import weakref
class BigObject:
pass
obj = BigObject()
ref = weakref.ref(obj)
print(ref()) # <BigObject instance>
del obj
print(ref()) # None (object was collected)Ciclos de referencias
Si A hace referencia a B y B hace referencia a A, ninguno llega a 0 aunque ambos sean inaccesibles. El GC cíclico de CPython detecta y recopila estos ciclos.
a = []
b = [a]
a.append(b) # cycle: a → b → a
del a, b
# Both are unreachable but refcount > 0
# The cyclic GC collects themEl módulo gc
El módulo gc proporciona el recolector de basura cíclico. Se ejecuta automáticamente, pero también puede activarse manualmente o deshabilitarse.
import gc
gc.collect() # force a collection cycle
print(gc.get_count()) # (gen0, gen1, gen2) allocation counts
print(gc.get_threshold()) # when each generation is collectedPools de memoria (pymalloc)
CPython asigna los objetos pequeños (< 512 bytes) desde su propio pool de memoria (pymalloc), que es más rápido que llamar a malloc para cada objeto pequeño.
# You do not call pymalloc directly — CPython uses it internally
# for all Python-level object allocations
# The pool pre-allocates large memory arenas
# and carves them into pools of fixed-size blocksFinalizadores __del__
__del__ se llama cuando el contador de referencias de un objeto llega a 0 (o más tarde si forma parte de un ciclo). Evite depender de él para la limpieza crítica; use gestores de contexto.
class Resource:
def __del__(self):
print(f"Freeing {self}")
# Better: use context manager
class SafeResource:
def __enter__(self): return self
def __exit__(self, *a): self.cleanup()Objetos compactos con __slots__
Los objetos con __slots__ utilizan menos memoria y requieren menos asignaciones, lo que reduce la presión sobre el GC.
import sys
class Reg:
def __init__(self, x, y): self.x, self.y = x, y
class Slotted:
__slots__ = ("x","y")
def __init__(self, x, y): self.x, self.y = x, y
print(sys.getsizeof(Reg(1,2))) # ~48 + dict overhead
print(sys.getsizeof(Slotted(1,2))) # ~48 (no dict)Deshabilitación del GC cíclico
En los programas que no crean ciclos de referencias, deshabilitar el GC cíclico puede mejorar el rendimiento.
import gc
gc.disable() # no cyclic GC — objects are only freed by refcounting
# Use only if you KNOW no cycles are created
# (pure functional/immutable data)
gc.enable() # re-enableComprobación rápida
¿Cuándo desasigna CPython inmediatamente un objeto?
Recapitulación
CPython realiza un seguimiento de los objetos mediante contadores de referencias. Cuando el contador llega a 0, se produce una desasignación inmediata. El GC cíclico gestiona los ciclos de referencias (módulo gc). Evite __del__ para la limpieza crítica; use gestores de contexto. Use __slots__ para reducir la memoria de cada objeto.
Preguntas frecuentes
¿La lección «Conteo de referencias en CPython» es gratis?
Sí — el texto completo de «Conteo de referencias en CPython» 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 «Conteo de referencias en CPython»?
Comprenda cómo CPython controla la vida útil de los objetos mediante recuentos 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 1 de 4.
¿Cuánto tiempo toma la lección «Conteo de referencias en CPython»?
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