0Pricing
Python Academy · Lezione

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))   # 3

sys.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 baseline

Incremento 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 → deallocated

Interning 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 them

Il 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 collected

Pool 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 blocks

Finalizzatori __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-enable

Verifica 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

  1. Conteggio dei riferimenti in CPython
  2. Garbage collector e riferimenti ciclici
  3. Profilazione con cProfile e line_profiler
  4. Profilazione della memoria con tracemalloc
← Torna a Python Academy