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)) # 3sys.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 baselineZwię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 → deallocatedInternowanie 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 themModuł 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 collectedPule 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 blocksFinalizatory __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-enableSzybkie 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
- Zliczanie odwołań w CPythonie
- Garbage collector i cykliczne odwołania
- Profilowanie za pomocą cProfile i line_profiler
- Profilowanie pamięci za pomocą tracemalloc