8.1 Słabe referencje w Javie
Istnieje kilka rodzajów odwołań w Javie.
Istnieje StrongReference - to najczęstsze linki, które tworzymy każdego dnia.
Object object = new Object();//created an object
object = null;//can now be garbage collected
Istnieją trzy „specjalne” typy linków - SoftReference, WeakReference, PhantomReference. W rzeczywistości istnieje tylko jedna różnica między wszystkimi typami linków - zachowanie GC z obiektami, do których się odnoszą. Bardziej szczegółowo omówimy specyfikę każdego typu łącza później, ale na razie wystarczy następująca wiedza:
- SoftReference to miękkie odniesienie, jeśli GC zobaczy, że obiekt jest dostępny tylko poprzez łańcuch miękkich odniesień, usunie go z pamięci. Może.
- WeakReference - słabe odniesienie, jeśli GC zobaczy, że obiekt jest dostępny tylko poprzez łańcuch słabych odniesień, to usunie go z pamięci.
- PhantomReference jest odwołaniem fantomowym, jeśli GC zobaczy, że obiekt jest dostępny tylko poprzez łańcuch odwołań fantomowych, usunie go z pamięci. Po kilku seriach GC.
Można również powiedzieć, że typy linków mają pewien stopień miękkości:
- Zwykłym łączem twardym jest dowolna zmienna typu referencyjnego. Nie oczyszczony przez moduł wyrzucania elementów bezużytecznych, zanim stanie się nieużywany.
- SoftReference . Obiekt nie spowoduje zużycia całej pamięci — gwarantuje się, że zostanie usunięty przed wystąpieniem błędu OutOfMemoryError. Może wcześniej, w zależności od implementacji Garbage Collectora.
- Słabe odniesienie . Słabszy miękki. Nie zapobiega usuwaniu obiektu; moduł wyrzucania elementów bezużytecznych ignoruje takie odwołania.
- PhantomReference . Używane do przetwarzania „śmierci” obiektu: obiekt jest dostępny po sfinalizowaniu, dopóki nie zostanie usunięty.
Jeśli nie jest jeszcze jasne, jaka jest różnica, nie martw się, wkrótce wszystko się ułoży. Szczegóły tkwią w szczegółach, a szczegóły pojawią się później.
8.2 WeakReference i SoftReference w Javie
Najpierw przyjrzyjmy się różnicy między WeakReference i SoftReference w Javie.
Krótko mówiąc, moduł wyrzucania elementów bezużytecznych zwolni pamięć obiektu, jeśli wskazują na niego tylko słabe odniesienia. Jeśli obiekt jest wskazywany przez SoftReferences, wówczas pamięć jest zwalniana, gdy JVM pilnie potrzebuje pamięci.
W niektórych przypadkach daje to zdecydowaną przewagę SoftReference nad Strong odniesienia. Na przykład SoftReference służy do implementacji pamięci podręcznej aplikacji, więc pierwszą rzeczą, jaką zrobi JVM, jest usunięcie obiektów, na które wskazują tylko SoftReferences.
WeakReference doskonale nadaje się do przechowywania metadanych, takich jak przechowywanie odniesień do modułu ładującego klasy. Jeśli żadna klasa nie jest załadowana, nie należy odwoływać się do ClassLoader. Właśnie dlatego WeakReference umożliwia odśmiecaczowi pracę na ClassLoader, gdy tylko ostatnie silne odwołanie do niego zostanie usunięte.
Przykład WeakReference w Javie:
// some object
Student student = new Student();
// weak reference to it
WeakReference weakStudent = new WeakReference(student);
// now the Student object can be garbage collected
student = null;
Przykład SoftReference w Javie:
// some object
Student student = new Student();
// weak reference to it
SoftReference softStudent = new SoftReference(student)
// now the Student object can be garbage collected
// but this will only happen if the JVM has a strong need for memory
student = null;
8.3 PhantomReference w Javie
Instancja PhantomReference jest tworzona w taki sam sposób jak w przykładach WeakReference i SoftReference, ale jest rzadko używana.
PhantomReference może zostać usunięty, jeśli obiekt nie ma silnych (Strong), słabych (WeakReference) lub miękkich (SoftReference) odniesień.
Możesz utworzyć obiekt Phantom Reference w następujący sposób:
PhantomReference myObjectRef = new PhantomReference(MyObject);
PhantomReference może być używany w sytuacjach, w których finalize() nie ma sensu. Ten typ referencyjny różni się od innych typów, ponieważ nie jest przeznaczony do uzyskiwania dostępu do obiektu. Jest to sygnał, że obiekt został już sfinalizowany, a Garbage Collector jest gotowy do odzyskania pamięci.
W tym celu moduł wyrzucania elementów bezużytecznych umieszcza go w specjalnej kolejce referencyjnej w celu dalszego przetwarzania. ReferenceQueue to miejsce, w którym umieszczane są odwołania do obiektów w celu zwolnienia pamięci.
Referencje fantomowe to bezpieczny sposób, aby wiedzieć, że obiekt został usunięty z pamięci. Rozważmy na przykład aplikację obsługującą duże obrazy. Powiedzmy, że chcemy załadować obraz do pamięci, gdy znajduje się on już w pamięci, która jest gotowa do wyczyszczenia elementów bezużytecznych. W takim przypadku chcemy poczekać, aż moduł wyrzucania elementów bezużytecznych zabije stary obraz przed załadowaniem nowego obrazu do pamięci.
Tutaj PhantomReference jest elastycznym i bezpiecznym wyborem. Odwołanie do starego obrazu zostanie przekazane do ReferenceQueue po zniszczeniu starego obiektu obrazu. Gdy już mamy ten link, możemy załadować nowy obraz do pamięci.