Python Academy · Lektion

CPython-referenceoptælling

Forstå, hvordan CPython sporer objekters levetid med referenceoptællere.

Lektion 1 af 413 trin

CPython-referenceoptælling er en gratis Python Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Python Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Python Academy-kurset indeholder 4 lektioner i alt.

Hvad er referencetælling?

CPython holder styr på hvert objekts referencetæller. Når tælleren falder til 0, bliver objektet straks deallokeret. Det er Pythons primære mekanisme til hukommelseshåndtering.

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) returnerer den aktuelle referencetæller. Bemærk: Et kald tilføjer 1 (referencen til funktionsargumentet).

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

Inkrementering og dekrementering

Hver tildeling øger tælleren, og hver sletning eller gentildeling mindsker den. Når tælleren når 0, kalder CPython objektets deallokeringsfunktion.

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

Objektinterning

CPython internerer små heltal (-5 til 256) og mange strengliteraler og genbruger det samme objekt. Sammenligninger med is afslører dette.

a = 256
b = 256
print(a is b)   # True (interned)

c = 257
d = 257
print(c is d)   # may be False (not interned)

Svage referencer

Svage referencer øger ikke referencetælleren. De er nyttige til at undgå at forhindre affaldsindsamling af objekter, som du vil observere, men ikke eje.

import weakref

class BigObject:
    pass

obj = BigObject()
ref = weakref.ref(obj)
print(ref())   # <BigObject instance>
del obj
print(ref())   # None (object was collected)

Referencencyklusser

Hvis A refererer til B, og B refererer til A, når ingen af dem 0, selv når begge er utilgængelige. CPythons cykliske GC registrerer og indsamler dem.

a = []
b = [a]
a.append(b)   # cycle: a → b → a
del a, b
# Both are unreachable but refcount > 0
# The cyclic GC collects them

Modulet gc

Modulet gc leverer den cykliske affaldsopsamler. Den kører automatisk, men kan udløses manuelt eller deaktiveres.

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

Hukommelsespuljer (pymalloc)

CPython allokerer små objekter (under 512 byte) fra sin egen hukommelsespulje (pymalloc), som er hurtigere end at kalde malloc for hvert lille objekt.

# 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

__del__-afsluttere

__del__ kaldes, når et objekts referencetæller når 0 (eller senere, hvis objektet indgår i en cyklus). Undgå at stole på den til kritisk oprydning — brug i stedet kontekstadministratorer.

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()

Kompakte objekter med __slots__

Objekter med __slots__ bruger mindre hukommelse og kræver færre allokeringer, hvilket mindsker belastningen på affaldsopsamlingen.

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)

Deaktivering af den cykliske GC

For programmer, der ikke opretter referencencyklusser, kan deaktivering af den cykliske GC forbedre gennemløbet.

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

Hurtigt tjek

Hvornår deallokerer CPython straks et objekt?

Opsummering

CPython holder styr på objekter via referencetællere. Når tælleren når 0 → øjeblikkelig deallokering. Referencencyklusser håndteres af den cykliske GC (modulet gc). Undgå __del__ til kritisk oprydning; brug kontekstadministratorer. Brug __slots__ til at reducere hukommelsesforbruget pr. objekt.

Gratis at komme i gang

Lær Python med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
76
Lektioner
320

Ofte stillede spørgsmål

Er lektionen “CPython-referenceoptælling” gratis?

Ja — hele teksten til “CPython-referenceoptælling” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Python Academy-kurset, skal du opgradere til CoddyKit PRO. Python Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “CPython-referenceoptælling”?

Forstå, hvordan CPython sporer objekters levetid med referenceoptællere. Du øver dig i Python Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Python Academy?

Der kræves ingen tidligere erfaring. Python Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “CPython-referenceoptælling”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Python Academy-lektion?

Ja. Alle Python Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. CPython-referenceoptælling
  2. Garbage collectoren og cykliske referencer
  3. Profilering med cProfile og line_profiler
  4. Hukommelsesprofilering med tracemalloc
← Tilbage til Python Academy