Middle+
Opowiedz o metodach działania zbieracza śmieci (Garbage Collector).
sobes.tech AI
Odpowiedź od AI
Zbieracz śmieci to proces automatycznego zarządzania pamięcią, który zwalnia pamięć zajętą przez obiekty, które nie są już używane przez program.
Główne metody działania zbieracza śmieci:
-
Licznik referencji:
- Każdy obiekt ma licznik, który przechowuje liczbę odwołań do niego.
- Tworząc odwołanie do obiektu, licznik rośnie.
- Gdy odwołanie znika (np. zmienna wychodzi z zakresu), licznik maleje.
- Gdy licznik osiąga zero, obiekt jest uważany za nieosiągalny i jego pamięć jest zwalniana.
- Problemy: Nie radzi sobie z referencjami cyklicznymi, gdy dwa lub więcej obiektów odwołuje się do siebie nawzajem, ale są nieosiągalne z zewnątrz.
-
Zbieracz śmieci typu tracing:
- Działa w dwóch etapach: oznaczanie i skanowanie lub kompresja.
- Etap oznaczania: Zaczyna od "korzeni" (set główny) - obiektów, które są gwarantowanie dostępne (np. zmienne globalne, obiekty na stosie). GC przechodzi przez wszystkie osiągalne z korzeni obiekty, oznaczając je jako "żywe".
- Etap skanowania: GC przeszukuje cały stos. Nieoznaczone obiekty są uważane za "śmieci" i ich pamięć jest zwalniana.
- Kompresja (opcjonalnie): Po skanowaniu GC może przesuwać "żywe" obiekty, aby wyeliminować fragmentację pamięci.
- Zalety: Może obsługiwać referencje cykliczne.
- Wady: Może powodować przerwy w wykonywaniu programu (stop-the-world), podczas gdy GC działa.
Najczęstsze algorytmy zbieraczy śmieci typu tracing:
- Mark-and-Sweep: Oznacza żywe obiekty, a następnie zbiera śmieci.
- Mark-and-Compact: Oznacza żywe obiekty, a następnie je przesuwa, aby zdefragmentować pamięć.
- Copying: Dzieli stertę na dwie połowy. Podczas zbierania GC kopiuje żywe obiekty z jednej połowy do drugiej, a następnie zwalnia oryginalną połowę.
- Generacyjny: Opiera się na hipotezie, że większość obiektów umiera młodo. Sterta jest podzielona na generacje (np. młoda i stara). GC częściej zbiera śmieci w młodej generacji, co prowadzi do krótszych przerw.
Konkretna metoda działania zbieracza śmieci zależy od używanego języka programowania i jego implementacji. Na przykład Java i C# używają różnych wariantów zbieraczy śmieci, w tym generacyjnych. Python tradycyjnie używał licznika referencji z dodatkowymi mechanizmami do wykrywania referencji cyklicznych, a w nowszych wersjach stosuje się również elementy zbierania typu tracing.