Użycie słabych referencji jest czymś, czego nigdy nie widziałem implementacji, więc próbuję dowiedzieć się, jaki jest ich przypadek użycia i jak ta implementacja będzie działać. Kiedy musiałeś użyć WeakHashMap
lub WeakReference
i jak był używany?
java
weak-references
18 Królik
źródło
źródło
Odpowiedzi:
Zrozumienie słabych odniesień , Ethan Nicholas
źródło
WeakHashMap
.WeakReference
przeciwSoftReference
Jedno rozróżnienie, które należy wyjaśnić, to różnica między a
WeakReference
i aSoftReference
.Zasadniczo
WeakReference
będzie to GC-d przez JVM chętnie, gdy obiekt, do którego istnieje odwołanie, nie ma do niego żadnych twardych odniesień. ZSoftReference
drugiej strony obiekt d będzie miał tendencję do pozostawiania go przez moduł odśmiecania, dopóki naprawdę nie będzie musiał odzyskać pamięci.Pamięć podręczna, w której wartości są przechowywane wewnątrz
WeakReference
s, byłaby całkiem bezużyteczna (w aWeakHashMap
, to klucze są słabo przywoływane).SoftReferences
są przydatne do zawijania wartości, gdy chcesz zaimplementować pamięć podręczną, która może rosnąć i zmniejszać się wraz z dostępną pamięcią.źródło
W szczególności jednym z powszechnych zastosowań
WeakReference
s iWeakHashMap
s jest dodawanie właściwości do obiektów. Czasami chcesz dodać jakąś funkcjonalność lub dane do obiektu, ale podklasy i / lub kompozycja nie są opcją w tym przypadku oczywistą rzeczą byłoby utworzenie hashmapy łączącej obiekt, który chcesz rozszerzyć, do właściwości, którą chcesz dodać . wtedy, gdy potrzebujesz nieruchomości, możesz ją po prostu sprawdzić na mapie. Jeśli jednak obiekty, do których dodajesz właściwości, są często niszczone i często tworzone, możesz skończyć z wieloma starymi obiektami na mapie, które zajmują dużo pamięci.Jeśli
WeakHashMap
zamiast tego użyjesz a, obiekty opuszczą twoją mapę, gdy tylko nie będą już używane przez resztę twojego programu, co jest zachowaniem pożądanym.Musiałem to zrobić, aby dodać jakieś dane
java.awt.Component
, aby ominąć zmianę pomiędzy JRE 1.4.2 i 1.5, mógłbym naprawić go przez instacji każdy składnik byłem zainteresowany int (JButton
,JFrame
,JPanel
....), ale było to o wiele łatwiej z dużo mniejszą ilością kodu.źródło
Innym przydatnym przypadkiem dla implementacji rejestru nasłuchiwania
WeakHashMap
iWeakReference
jest .Kiedy tworzysz coś, co chce posłuchać określonych wydarzeń, zazwyczaj rejestrujesz słuchacza, np
Jeśli
manager
przechowuje twój słuchacz z aWeakReference
, oznacza to, że nie musisz usuwać rejestru, np. Z a,manager.removeListener(myListenerImpl)
ponieważ zostanie on automatycznie usunięty, gdy twój słuchacz lub twój komponent, który go trzyma, stanie się niedostępny.Oczywiście nadal możesz ręcznie usunąć nasłuchiwanie, ale jeśli tego nie zrobisz lub zapomnisz, nie spowoduje to wycieku pamięci i nie zapobiegnie gromadzeniu elementów bezużytecznych.
Gdzie pojawia
WeakHashMap
się ten obraz?Rejestr odbiornika, który chce przechowywać zarejestrowane odbiorniki jako
WeakReference
s, potrzebuje kolekcji do przechowywania tych odniesień. WWeakHashSet
standardowej bibliotece Javy nie ma implementacji,WeakHashMap
ale możemy z łatwością wykorzystać tę drugą do „zaimplementowania” funkcjonalności pierwszej:Mając to
listenerSet
na zarejestrowanie nowego słuchacza wystarczy dodać go do zestawu, a nawet jeśli to nie jest usuwany wyraźnie, gdy słuchacz nie jest wymieniony, zostanie on automatycznie usunięty przez JVM.źródło
WeakHashMap
dotyczy sytuacji, gdy potrzebujeszHashMap
obiektów. Więc wow, nie musisz ręcznie wykonywać hashmap.remove , ponieważ elementy są automatycznie usuwane, gdy obiekt znajdzie się poza zasięgiem! Dosłownie magia! Taka brzydka magiczna sztuczka to kompletny facepalm .WeakReference
plików znacznie upraszcza podstawę kodu i pozwala uniknąć niepotrzebnych błędów związanych z niepowodzeniem anulowania subskrypcji. Jaki minus?Ten wpis na blogu demonstruje użycie obu klas: Java: synchronizacja na podstawie identyfikatora . Użycie wygląda mniej więcej tak:
IdMutextProvider zapewnia obiekty oparte na identyfikatorach do synchronizacji. Wymagania są następujące:
Osiąga się to za pomocą wewnętrznej mapy pamięci typu:
Obiekt jest jednocześnie kluczem i wartością. Gdy nic poza mapą nie ma twardego odniesienia do obiektu, może zostać wyrzucone do pamięci. Wartości w mapie są przechowywane z twardymi odwołaniami, więc wartość musi być opakowana w WeakReference, aby zapobiec wyciekowi pamięci. Ten ostatni punkt omówiono w pliku javadoc .
źródło
Jeśli na przykład chcesz śledzić wszystkie obiekty utworzone w określonej klasie. Aby nadal zezwalać na zbieranie elementów bezużytecznych, zachowujesz listę / mapę słabych odniesień do obiektów zamiast samych obiektów.
Gdyby ktoś mógł mi wyjaśnić odniesienia do widm, byłbym szczęśliwy ...
źródło
Jak stwierdzono powyżej, słabe odniesienie utrzymuje się tak długo, jak istnieje silne odniesienie.
Przykładowym zastosowaniem może być użycie WeakReference wewnątrz detektorów, tak aby nasłuchiwacze nie byli już aktywni po zniknięciu głównego odniesienia do ich obiektu docelowego. Należy zauważyć, że nie oznacza to, że WeakReference jest usuwane z listy słuchaczy, czyszczenie jest nadal wymagane, ale można je wykonać na przykład w zaplanowanych godzinach. Ma to również wpływ na to, że słuchany obiekt nie posiada silnych odniesień i ostatecznie staje się źródłem nadmiaru pamięci. Przykład: komponenty Swing GUI odwołujące się do modelu mającego dłuższy cykl życia niż okno.
Podczas zabawy ze słuchaczami, jak opisano powyżej, szybko zdaliśmy sobie sprawę, że obiekty są zbierane „natychmiast” z punktu widzenia użytkownika.
źródło
WeakReferences
Twój komentarz jest całkowicie błędny!Jednym z rzeczywistych zastosowań, jakie miałem dla WeakReferences, jest pojedynczy, bardzo duży obiekt, który jest rzadko używany. Nie chcesz mieć tego w pamięci, gdy nie jest potrzebny; ale jeśli inny wątek potrzebuje tego samego obiektu, nie chcesz też dwóch z nich w pamięci. Możesz przechowywać gdzieś słabe odniesienie do obiektu, a twarde odniesienia w metodach, które go używają; gdy obie metody zakończą się, obiekt zostanie zebrany.
źródło
Wyszukałem w google hasło „nowa WeakHashMap ()”.
Mam kilka dopasowań z projektu GNU classpath i
źródło
możesz użyć slabyhashmap, aby zaimplementować buforowanie bez zasobów do ekspansywnego tworzenia obiektów.
ale zauważ, że nie jest pożądane posiadanie zmiennych obiektów. Użyłem go do buforowania wyników zapytań (których wykonanie zajmuje około 400 ms) do wyszukiwarki tekstowej, która rzadko jest aktualizowana.
źródło