0Pricing
Python Academy · Lekcja

Zliczanie odwołań w CPythonie

Proszę zrozumieć, jak CPython śledzi czas życia obiektów za pomocą liczników odwołań.

Zliczanie odwołań w CPythonie to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.

Czym jest zliczanie referencji?

CPython śledzi licznik referencji każdego obiektu. Gdy licznik spadnie do 0, obiekt jest natychmiast dealokowany. Jest to podstawowy mechanizm zarządzania pamięcią w Pythonie.

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) zwraca bieżący licznik referencji. Uwaga: wywołanie tej funkcji zwiększa go o 1, ponieważ tworzy referencję dla argumentu funkcji.

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

Zwiększanie i zmniejszanie licznika

Każde przypisanie zwiększa licznik, a każde usunięcie lub ponowne przypisanie go zmniejsza. Gdy licznik osiągnie 0, CPython wywołuje dealokator obiektu.

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

Internowanie obiektów

CPython internuje małe liczby całkowite (od -5 do 256) oraz wiele literałów tekstowych, ponownie wykorzystując ten sam obiekt. Porównania za pomocą is pozwalają to wykryć.

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

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

Słabe referencje

Słabe referencje nie zwiększają licznika referencji. Są przydatne, gdy chcą Państwo obserwować obiekty, ale nie przejmować ich własności i nie uniemożliwiać ich zbierania przez garbage collector.

import weakref

class BigObject:
    pass

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

Cykle referencji

Jeśli A odwołuje się do B, a B do A, żaden z obiektów nie osiągnie wartości 0, nawet gdy oba są nieosiągalne. Cykliczny garbage collector CPythona wykrywa takie cykle i je zbiera.

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

Moduł gc

Moduł gc udostępnia cykliczny garbage collector. Działa on automatycznie, ale można go uruchomić ręcznie lub wyłączyć.

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

Pule pamięci (pymalloc)

CPython alokuje małe obiekty (< 512 bajtów) z własnej puli pamięci (pymalloc), która jest szybsza niż wywoływanie malloc dla każdego małego obiektu.

# 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

Finalizatory __del__

__del__ jest wywoływana, gdy licznik referencji obiektu osiągnie 0, lub później, jeśli obiekt należy do cyklu. Nie należy polegać na niej w przypadku krytycznego sprzątania — zamiast tego proszę używać menedżerów kontekstu.

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

Kompaktowe obiekty z __slots__

Obiekty z __slots__ zużywają mniej pamięci i wymagają mniejszej liczby alokacji, zmniejszając obciążenie GC.

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)

Wyłączanie cyklicznego GC

W programach, które nie tworzą cykli referencji, wyłączenie cyklicznego GC może poprawić przepustowość.

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

Szybkie sprawdzenie

Kiedy CPython natychmiast dealokuje obiekt?

Podsumowanie

CPython śledzi obiekty za pomocą liczników referencji. Osiągnięcie wartości 0 oznacza natychmiastową dealokację. Cykle referencji są obsługiwane przez cykliczny GC (moduł gc). W przypadku krytycznego sprzątania należy unikać __del__ i używać menedżerów kontekstu. __slots__ pozwala zmniejszyć ilość pamięci przypadającą na obiekt.

Często zadawane pytania

Czy lekcja „Zliczanie odwołań w CPythonie” jest bezpłatna?

Tak — pełny tekst „Zliczanie odwołań w CPythonie” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Zliczanie odwołań w CPythonie”?

Proszę zrozumieć, jak CPython śledzi czas życia obiektów za pomocą liczników odwołań. Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Python Academy?

Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Zliczanie odwołań w CPythonie”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?

Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Zliczanie odwołań w CPythonie
  2. Garbage collector i cykliczne odwołania
  3. Profilowanie za pomocą cProfile i line_profiler
  4. Profilowanie pamięci za pomocą tracemalloc
← Powrót do Python Academy