Odśmiecanie w zasadzie oznacza po prostu, że przydzielone obiekty są automatycznie zwalniane w pewnym momencie, gdy nie są już osiągalne.
Mówiąc dokładniej, są one uwalniane, gdy stają się nieosiągalne dla programu, ponieważ w przeciwnym razie obiekty o odwołaniach cyklicznych nigdy nie zostałyby uwolnione.
Inteligentne wskaźniki odnoszą się tylko do dowolnej struktury, która zachowuje się jak zwykły wskaźnik, ale ma dołączoną dodatkową funkcjonalność. Należą do nich między innymi zwolnienie, ale także kopiowanie przy zapisie, powiązane kontrole, ...
Teraz, jak już wspomniałeś, inteligentnych wskaźników można użyć do zaimplementowania formy wyrzucania elementów bezużytecznych.
Ale tok myślenia idzie w następujący sposób:
- Odśmiecanie jest fajną rzeczą, ponieważ jest wygodne i muszę zająć się mniejszą liczbą rzeczy
- Dlatego: Chcę zbieranie śmieci w moim języku
- Jak mogę wprowadzić GC do mojego języka?
Oczywiście możesz to zaprojektować w ten sposób od samego początku. C # został zaprojektowany do zbierania śmieci, więc po prostu new
twój obiekt i zostanie zwolniony, gdy referencje wypadną poza zakres. To, jak zostanie to zrobione, zależy od kompilatora.
Ale w C ++ nie było przeznaczone wyrzucanie elementów bezużytecznych. Jeśli przydzielimy jakiś wskaźnik int* p = new int;
i wypadnie on poza zasięg, p
sam zostanie usunięty ze stosu, ale nikt nie zajmie się przydzieloną pamięcią.
Teraz jedyne, co masz od samego początku, to deterministyczne niszczyciele . Kiedy obiekt opuszcza zakres, w którym został utworzony, wywoływany jest jego destruktor. W połączeniu z szablonami i przeciążeniem operatora można zaprojektować obiekt otoki, który zachowuje się jak wskaźnik, ale wykorzystuje funkcje destruktora do czyszczenia podłączonych do niego zasobów (RAII). Nazywasz to inteligentnym wskaźnikiem .
Wszystko to jest ściśle specyficzne dla C ++: przeciążenie operatora, szablony, destruktory, ... W tej konkretnej sytuacji językowej opracowałeś inteligentne wskaźniki, które zapewnią ci GC, którego potrzebujesz.
Ale jeśli projektujesz język za pomocą GC od samego początku, jest to jedynie szczegół implementacji. Po prostu mówisz, że obiekt zostanie wyczyszczony, a kompilator zrobi to za ciebie.
Inteligentne wskaźniki, takie jak w C ++, prawdopodobnie nie byłyby nawet możliwe w językach takich jak C #, które nie mają żadnego deterministycznego zniszczenia (C # działa w tym celu, zapewniając cukier składniowy do wywoływania .Dispose()
określonych obiektów). Zasoby niereferencyjne zostaną w końcu odzyskane przez GC, ale nie określono, kiedy dokładnie to nastąpi.
A to z kolei może pozwolić GC na bardziej wydajną pracę. Wbudowany głębiej w język niż inteligentne wskaźniki, które są na nim ustawione, .NET GC może np. Opóźniać operacje pamięci i wykonywać je w blokach, aby były tańsze lub nawet przenosić pamięć w celu zwiększenia wydajności w zależności od częstotliwości obiektów są dostępne.