Python Academy · leksjon

Garbage collector og sykliske referanser

Lær hvordan gc-modulen håndterer referansesykluser.

Leksjon 2 av 413 trinn

Garbage collector og sykliske referanser er en gratis leksjon i Python Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Python Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Python Academy inneholder totalt 4 leksjoner.

Hvorfor referansetelling ikke er nok

Referansetelling kan ikke samle inn objekter som inngår i referansesykluser – hvert objekt holder en referanse til det andre, slik at ingen av tellingene synker til 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

gc-modulen

gc er den sykliske søppelinnsamleren. Den skanner med jevne mellomrom sporede objekter etter utilgjengelige sykluser og samler dem inn.

import gc

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

Generasjonsbasert innsamling

GC bruker tre generasjoner. Nye objekter starter i gen 0. Objekter som overlever en innsamling, forfremmes. Gen 0 samles inn oftest.

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

Oppdage sykluser med gc.get_referents

Undersøk hvilke objekter et objekt refererer til – nyttig for å forstå hvorfor noe ikke blir samlet inn.

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() returnerer alle objekter som for øyeblikket spores av GC. Nyttig for å finne minnelekkasjer.

import gc

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

Unngå sykluser

Utform datastrukturer slik at De unngår sykluser: bruk svake referanser for bakoverreferanser, bruk ID-er i stedet for direkte referanser, eller bryt sykluser eksplisitt før objektene går ut av omfang.

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__ og sykluser

Objekter med __del__ som inngår i en syklus, kan ikke samles inn automatisk. De plasseres i gc.garbage i stedet.

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+

gc.freeze() fryser objekter som for øyeblikket spores, slik at de aldri samles inn. Dette er nyttig i langvarige prosesser etter oppstart for å redusere GC-pauser.

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

Deaktivere og aktivere GC igjen

Deaktiver syklisk GC i trange løkker der De vet at det ikke finnes sykluser, og aktiver den deretter igjen og tving frem en innsamling.

import gc

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

isenabled og isfinalized

Kontroller GC-tilstanden med gc.isenabled(), og finn ut om et objekt er i ferd med å bli finalisert med gc.is_finalized(obj).

import gc

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

Mønstre for minnelekkasjer

Vanlige årsaker til minnelekkasjer i Python er globale cacher som vokser uten grenser, hendelseslyttere som ikke kobles fra, referansesykluser med __del__ og C-utvidelser som lekker referanser.

# 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

Hurtigsjekk

Hva skjer med objekter med __del__ som inngår i en referansesyklus?

Oppsummering

Den sykliske GC-en håndterer referansesykluser som referansetelling ikke kan samle inn. Den bruker tre generasjoner og forfremmer objekter som overlever. Unngå sykluser med svake referanser. Objekter med __del__ i sykluser havner i gc.garbage. Bruk gc.freeze() etter oppstart for å redusere GC-pauser i langvarige servere.

Gratis å komme i gang

Lær deg Python med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
76
Leksjoner
320

Ofte stilte spørsmål

Er leksjonen «Garbage collector og sykliske referanser» gratis?

Ja – hele teksten i «Garbage collector og sykliske referanser» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Python Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Python Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Garbage collector og sykliske referanser»?

Lær hvordan gc-modulen håndterer referansesykluser. Du øver på Python Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Python Academy?

Ingen tidligere erfaring er nødvendig. Python Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.

Hvor lang tid tar leksjonen «Garbage collector og sykliske referanser»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Python Academy-leksjonen?

Ja. Alle Python Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Referansetelling i CPython
  2. Garbage collector og sykliske referanser
  3. Profilering med cProfile og line_profiler
  4. Minneprofilering med tracemalloc
← Tilbake til Python Academy