0Pricing
Python Academy · Leçon

Ramasse-miettes et références cycliques

Découvrez comment le module gc gère les cycles de références.

Ramasse-miettes et références cycliques est une leçon Python Academy gratuite sur CoddyKit. Ceci est la leçon 2 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.

Pourquoi le comptage des références ne suffit pas

Le comptage des références ne peut pas récupérer les objets impliqués dans des cycles de références : chacun conserve une référence vers l’autre, et aucun compteur n’atteint donc 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 them

Le module gc

gc est le ramasse-miettes cyclique. Il analyse périodiquement les objets suivis afin de trouver les cycles inaccessibles et de les récupérer.

import gc

gc.collect()   # trigger immediately
print(gc.garbage)   # objects with __del__ in cycles (cannot auto-collect)

Récupération générationnelle

Le ramasse-miettes utilise trois générations. Les nouveaux objets commencent dans la génération 0. Les objets qui survivent à une récupération sont promus. La génération 0 est récupérée le plus fréquemment.

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

Détecter les cycles avec gc.get_referents

Examinez les objets auxquels un objet fait référence : c’est utile pour comprendre pourquoi un objet n’est pas récupéré.

import gc

a = []
b = [a]
a.append(b)

for ref in gc.get_referents(a):
    print(ref)   # shows b

gc.get_objects()

gc.get_objects() renvoie tous les objets actuellement suivis par le ramasse-miettes. C’est utile pour trouver les fuites de mémoire.

import gc

before = len(gc.get_objects())
create_lots_of_objects()
after = len(gc.get_objects())
print(f"Leaked: {after - before} objects")

Éviter les cycles

Concevez les structures de données de manière à éviter les cycles : utilisez des références faibles pour les références inverses, des identifiants plutôt que des références directes, ou rompez explicitement les cycles avant que les objets ne sortent de portée.

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__ et les cycles

Les objets avec __del__ qui participent à un cycle ne peuvent pas être récupérés automatiquement. Ils sont placés dans gc.garbage à la place.

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 collect

gc.freeze() — Python 3.7 et versions ultérieures

gc.freeze() fige les objets actuellement suivis afin qu’ils ne soient jamais récupérés. Cette fonction est utile dans les processus de longue durée après le démarrage, pour réduire les pauses du ramasse-miettes.

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 servers

Désactiver et réactiver le ramasse-miettes

Désactivez le ramasse-miettes cyclique dans les boucles serrées où vous savez qu’il n’existe aucun cycle, puis réactivez-le et forcez une récupération ensuite.

import gc

gc.disable()
try:
    result = tight_loop_no_cycles()
finally:
    gc.enable()
    gc.collect()

isenabled et isfinalized

Vérifiez l’état du ramasse-miettes avec gc.isenabled() et détectez si un objet est en cours de finalisation avec gc.is_finalized(obj).

import gc

print(gc.isenabled())      # True by default
obj = object()
print(gc.is_finalized(obj))  # False (still alive)

Schémas de fuites de mémoire

Causes courantes des fuites de mémoire en Python : caches globaux qui croissent sans limite, écouteurs d’événements non détachés, références cycliques avec __del__ et extensions C qui perdent des références.

# 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 detach

Vérification rapide

Qu’advient-il des objets avec __del__ qui participent à un cycle de références ?

Récapitulatif

Le ramasse-miettes cyclique gère les cycles de références que le comptage des références ne peut pas récupérer. Il utilise trois générations et promeut les objets survivants. Évitez les cycles avec des références faibles. Les objets avec __del__ qui participent à des cycles finissent dans gc.garbage. Utilisez gc.freeze() après le démarrage pour réduire les pauses du ramasse-miettes dans les serveurs de longue durée.

Questions Fréquemment Posées

La leçon « Ramasse-miettes et références cycliques » est-elle gratuite ?

Oui — le texte complet de « Ramasse-miettes et références cycliques » 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 « Ramasse-miettes et références cycliques » ?

Découvrez comment le module gc gère les cycles 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 2 sur 4.

Combien de temps prend la leçon « Ramasse-miettes et références cycliques » ?

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

  1. Comptage des références dans CPython
  2. Ramasse-miettes et références cycliques
  3. Profilage avec cProfile et line_profiler
  4. Profilage mémoire avec tracemalloc
← Retour à Python Academy