Conteggio dei riferimenti in CPython
Comprenda come CPython tracci la durata degli oggetti con i contatori dei riferimenti.
Conteggio dei riferimenti in CPython è una lezione Python Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Python Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Python Academy include 4 lezioni in totale.
Che cos'è il conteggio dei riferimenti?
CPython tiene traccia del conteggio dei riferimenti di ogni oggetto. Quando il conteggio scende a 0, l'oggetto viene deallocato immediatamente. Questo è il principale meccanismo di gestione della memoria di 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) restituisce il conteggio dei riferimenti corrente. Nota: chiamarlo aggiunge 1, cioè il riferimento all'argomento della funzione.
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 e decremento
Ogni assegnazione incrementa il conteggio; ogni eliminazione o riassegnazione lo decrementa. Quando il conteggio raggiunge 0, CPython chiama il deallocatore dell'oggetto.
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 → deallocatedInterning degli oggetti
CPython internizza gli interi piccoli (da -5 a 256) e molte stringhe letterali, riutilizzando lo stesso oggetto. I confronti con is lo rivelano.
a = 256
b = 256
print(a is b) # True (interned)
c = 257
d = 257
print(c is d) # may be False (not interned)Riferimenti deboli
I riferimenti deboli non incrementano il conteggio dei riferimenti. Sono utili per evitare di impedire la garbage collection degli oggetti che desidera osservare senza possederli.
import weakref
class BigObject:
pass
obj = BigObject()
ref = weakref.ref(obj)
print(ref()) # <BigObject instance>
del obj
print(ref()) # None (object was collected)Cicli di riferimenti
Se A fa riferimento a B e B fa riferimento ad A, nessuno dei due raggiunge 0, anche quando entrambi sono irraggiungibili. Il GC ciclico di CPython rileva e raccoglie questi cicli.
a = []
b = [a]
a.append(b) # cycle: a → b → a
del a, b
# Both are unreachable but refcount > 0
# The cyclic GC collects themIl modulo gc
Il modulo gc fornisce il garbage collector ciclico. Viene eseguito automaticamente, ma può essere attivato manualmente o disabilitato.
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 collectedPool di memoria (pymalloc)
CPython alloca gli oggetti piccoli (< 512 byte) dal proprio pool di memoria (pymalloc), più velocemente di quanto farebbe chiamando malloc per ogni oggetto piccolo.
# 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 blocksFinalizzatori __del__
__del__ viene chiamato quando il conteggio dei riferimenti di un oggetto raggiunge 0, oppure più tardi se l'oggetto si trova in un ciclo. Eviti di farvi affidamento per la pulizia essenziale: utilizzi invece i context manager.
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()Oggetti compatti con __slots__
Gli oggetti con __slots__ utilizzano meno memoria e richiedono meno allocazioni, riducendo la pressione sul 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)Disabilitazione del GC ciclico
Nei programmi che non creano cicli di riferimenti, disabilitare il GC ciclico può migliorare la velocità di elaborazione.
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-enableVerifica rapida
Quando CPython dealloca immediatamente un oggetto?
Riepilogo
CPython tiene traccia degli oggetti tramite i conteggi dei riferimenti. Il conteggio raggiunge 0 → deallocazione immediata. I cicli di riferimenti vengono gestiti dal GC ciclico, il modulo gc. Eviti __del__ per la pulizia essenziale; utilizzi i context manager. Utilizzi __slots__ per ridurre la memoria per oggetto.
Domande Frequenti
La lezione «Conteggio dei riferimenti in CPython» è gratuita?
Sì — il testo completo di «Conteggio dei riferimenti in CPython» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Python Academy, passa a CoddyKit PRO. Il corso Python Academy include 4 lezioni in totale.
Cosa imparerò in «Conteggio dei riferimenti in CPython»?
Comprenda come CPython tracci la durata degli oggetti con i contatori dei riferimenti. Eserciti Python Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Python Academy?
Non è richiesta alcuna esperienza precedente. Python Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Conteggio dei riferimenti in CPython»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Python Academy?
Sì. Ogni lezione Python Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Conteggio dei riferimenti in CPython
- Garbage collector e riferimenti ciclici
- Profilazione con cProfile e line_profiler
- Profilazione della memoria con tracemalloc