Python Language Garbage Collector pour les cycles de référence


Exemple

La seule fois où le ramasse-miettes est nécessaire, c'est si vous avez un cycle de référence . L'exemple simple d'un cycle de référence est celui dans lequel A désigne B et B désigne A, tandis que rien d'autre ne fait référence à A ou B. Ni A ni B ne sont accessibles de n'importe où dans le programme, ils peuvent donc être détruits en toute sécurité. cependant, leurs comptages de référence sont 1 et ils ne peuvent donc pas être libérés par l'algorithme de comptage de référence seul.

>>> import gc; gc.disable()  # disable garbage collector
>>> class Track:
        def __init__(self):
            print("Initialized")
        def __del__(self):
            print("Destructed")
>>> A = Track()
Initialized
>>> B = Track()
Initialized
>>> A.other = B
>>> B.other = A
>>> del A; del B  # objects are not destructed due to reference cycle
>>> gc.collect()  # trigger collection
Destructed
Destructed
4

Un cycle de référence peut être arbitrairement long. Si A pointe vers B pointe vers C pointe sur ... pointe vers Z qui pointe sur A, alors ni A ni Z ne seront collectés, jusqu'à la phase de récupération de place:

>>> objs = [Track() for _ in range(10)]
Initialized
Initialized
Initialized
Initialized
Initialized
Initialized
Initialized
Initialized
Initialized
Initialized
>>> for i in range(len(objs)-1):
...     objs[i].other = objs[i + 1]
...
>>> objs[-1].other = objs[0]  # complete the cycle
>>> del objs                  # no one can refer to objs now - still not destructed
>>> gc.collect()
Destructed
Destructed
Destructed
Destructed
Destructed
Destructed
Destructed
Destructed
Destructed
Destructed
20