Comptage des références dans CPython
Comprenez comment CPython suit la durée de vie des objets grâce aux compteurs de références.
Comptage des références dans CPython est une leçon Python Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Python Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Python Academy comprend 4 leçons au total.
Qu’est-ce que le comptage des références ?
CPython suit le compteur de références de chaque objet. Lorsque ce compteur atteint 0, l’objet est immédiatement désalloué. Il s’agit du principal mécanisme de gestion de la mémoire 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) renvoie le compteur de références actuel. Attention : l’appel ajoute 1 au compteur, en raison de la référence de l’argument de la fonction.
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 baselineIncrémentation et décrémentation
Chaque affectation incrémente le compteur ; chaque suppression ou nouvelle affectation le décrémente. Lorsque le compteur atteint 0, CPython appelle le désallocateur de l’objet.
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 → deallocatedInternement des objets
CPython interne les petits entiers (de -5 à 256) ainsi que de nombreux littéraux de chaîne, en réutilisant le même objet. Les comparaisons avec is permettent de le constater.
a = 256
b = 256
print(a is b) # True (interned)
c = 257
d = 257
print(c is d) # may be False (not interned)Références faibles
Les références faibles n’incrémentent pas le compteur de références. Elles sont utiles pour éviter d’empêcher le ramasse-miettes de récupérer les objets que vous souhaitez observer sans en être propriétaire.
import weakref
class BigObject:
pass
obj = BigObject()
ref = weakref.ref(obj)
print(ref()) # <BigObject instance>
del obj
print(ref()) # None (object was collected)Cycles de références
Si A fait référence à B et B fait référence à A, aucun des deux compteurs n’atteint 0, même lorsque les deux objets sont inaccessibles. Le ramasse-miettes cyclique de CPython détecte et récupère ces objets.
a = []
b = [a]
a.append(b) # cycle: a → b → a
del a, b
# Both are unreachable but refcount > 0
# The cyclic GC collects themLe module gc
Le module gc fournit le ramasse-miettes cyclique. Il s’exécute automatiquement, mais peut être déclenché manuellement ou désactivé.
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 collectedRéservoirs de mémoire (pymalloc)
CPython alloue les petits objets (moins de 512 octets) dans son propre réservoir de mémoire (pymalloc), plus rapide que l’appel à malloc pour chaque petit objet.
# 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 blocksFinaliseurs __del__
__del__ est appelé lorsque le compteur de références d’un objet atteint 0 (ou plus tard si l’objet fait partie d’un cycle). Évitez de vous y fier pour le nettoyage critique : utilisez plutôt des gestionnaires de contexte.
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()Objets compacts avec __slots__
Les objets utilisant __slots__ consomment moins de mémoire et nécessitent moins d’allocations, ce qui réduit la pression exercée sur le ramasse-miettes.
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)Désactiver le ramasse-miettes cyclique
Pour les programmes qui ne créent pas de cycles de références, désactiver le ramasse-miettes cyclique peut améliorer le débit.
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-enableVérification rapide
Quand CPython désalloue-t-il immédiatement un objet ?
Récapitulatif
CPython suit les objets au moyen de compteurs de références. Lorsque le compteur atteint 0 → désallocation immédiate. Les cycles de références sont gérés par le ramasse-miettes cyclique (module gc). Évitez __del__ pour le nettoyage critique : utilisez des gestionnaires de contexte. Utilisez __slots__ pour réduire la mémoire utilisée par objet.
Questions Fréquemment Posées
La leçon « Comptage des références dans CPython » est-elle gratuite ?
Oui — le texte complet de « Comptage des références dans CPython » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Python Academy, passe à CoddyKit PRO. Le cours Python Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Comptage des références dans CPython » ?
Comprenez comment CPython suit la durée de vie des objets grâce aux compteurs de références. Tu pratiques Python Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Python Academy ?
Aucune expérience préalable n'est requise. Python Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.
Combien de temps prend la leçon « Comptage des références dans CPython » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Python Academy ?
Oui. Chaque leçon Python Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Comptage des références dans CPython
- Ramasse-miettes et références cycliques
- Profilage avec cProfile et line_profiler
- Profilage mémoire avec tracemalloc