Kiedy można użyć WeakHashMap lub WeakReference?

Użycie słabych odniesień jest czymś, czego nigdy nie widziałem implementacji, więc staram się dowiedzieć, jaki jest dla nich przypadek użycia i jak implementacja będzie działać. Kiedy trzeba było użyć WeakHashMap LUB WeakReference i jak to było używane?

Author: David Newcomb, 2008-09-30

10 answers

Jednym z problemów z silnymi referencjami jest buforowania, szczególnie przy bardzo dużych struktury jak obrazy. Załóżmy, że mieć aplikację, która musi działać z dostarczonymi przez użytkownika obrazami, takimi jak narzędzie do projektowania stron internetowych, nad którym pracuję. Naturalnie chcesz je buforować obrazów, ponieważ ładowanie ich z dysku jest bardzo drogie i chcesz unikaj możliwości posiadania dwóch kopie (potencjalnie gigantyczne) obraz w pamięci na raz.

Ponieważ bufor obrazu jest powinien uniemożliwia nam przeładowanie obrazów, gdy nie musimy absolutnie, będziesz szybko uświadomić sobie, że pamięć podręczna powinna zawsze zawierać odniesienie do dowolnego obraz, który jest już w pamięci. Z zwykłe mocne odniesienia, choć, to samo odniesienie wymusi obraz, który pozostanie w pamięci, co wymaga, abyś w jakiś sposób ustalił, kiedy obraz nie jest już potrzebny w pamięć i usuń ją z pamięci podręcznej, tak, że staje się uprawniony do wywóz śmieci. Ty są zmuszeni do Duplikuj zachowanie śmieci kolektor i ręcznie określić czy przedmiot powinien być w pamięć.

Zrozumienie Słabych Odniesień , Ethan Nicholas

 96
Author: Jacob Krall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-17 12:20:12

WeakReference kontra SoftReference

Rozróżnienie, które należy wyjaśnić, to różnica między WeakReference i a SoftReference.

Zasadniczo WeakReferencebędzie GC-dprzez JVMchętnie, gdy obiekt odniesienia nie ma twardych odniesień do niego. Z drugiej strony obiekt SoftReferenced będzie zwykle pozostawiany przez garbage collector, dopóki nie będzie musiał odzyskać pamięci.

Bufor, w którym przechowywane są wartości WeakReference S byłoby dość bezużyteczne(w WeakHashMap, to klucze są słabo odwołane). SoftReferences są przydatne do owijania wartości wokół, gdy chcesz zaimplementować pamięć podręczną, która może rosnąć i kurczyć się z dostępną pamięcią.

 57
Author: oxbow_lakes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-25 04:58:19

Jednym z powszechnych zastosowań WeakReference s I WeakHashMap S w szczególności jest dodawanie właściwości do obiektów. Czasami chcesz dodać jakąś funkcjonalność lub dane do obiektu, ale podklasowanie i / lub kompozycja nie są opcją w takim przypadku oczywistą rzeczą do zrobienia byłoby utworzenie hashmapy łączącej obiekt, który chcesz rozszerzyć, z właściwością, którą chcesz dodać. wtedy, gdy potrzebujesz Nieruchomości, możesz po prostu sprawdzić ją na mapie. Jeśli jednak obiekty, które dodajesz do właściwości, mają tendencję do uzyskiwania zniszczone i stworzone dużo, można skończyć z wielu starych obiektów na mapie zajmuje dużo pamięci.

Jeśli zamiast tego użyjesz WeakHashMap obiekty opuszczą Twoją mapę, gdy tylko nie będą już używane przez resztę programu, co jest pożądanym zachowaniem.

Musiałem to zrobić, aby dodać trochę danych do java.awt.Component, aby ominąć zmianę w JRE między 1.4.2 a 1.5, mogłem to naprawić przez podklasowanie każdego komponentu, który byłem zainteresowany int (JButton, JFrame, JPanel....) ale to było znacznie łatwiejsze przy znacznie mniejszej ilości kodu.

 30
Author: luke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-04 18:25:17

Innym przydatnym przypadkiem dla WeakHashMap i WeakReference jest implementacja rejestru listenera .

Kiedy tworzysz coś, co chce słuchać pewnych zdarzeń, zazwyczaj rejestrujesz słuchacza, np.

manager.registerListener(myListenerImpl);

Jeśli manager przechowuje Twój listener za pomocą WeakReference, oznacza to, że nie musisz usuwać rejestru np. za pomocą manager.removeListener(myListenerImpl), ponieważ zostanie on automatycznie usunięty, gdy twój listener lub komponent trzymający listener stanie się niedostępny.

Oczywiście, że ty nadal można ręcznie usunąć słuchacza, Ale jeśli tego nie zrobisz lub zapomnisz, nie spowoduje to wycieku pamięci i nie zapobiegnie zbieraniu śmieci przez słuchacza.

Gdzie WeakHashMap pojawia się na zdjęciu?

Rejestr słuchaczy, który chce przechowywać zarejestrowanych słuchaczy jako WeakReference S, potrzebuje kolekcji do przechowywania tych referencji. Nie ma implementacji WeakHashSet w standardowej bibliotece Javy tylko WeakHashMap, ale możemy z łatwością użyć tej drugiej do "zaimplementuj" funkcjonalność pierwszego z nich:

Set<ListenerType> listenerSet =
    Collections.newSetFromMap(new WeakHashMap<ListenerType, Boolean>());

Z tym listenerSet aby zarejestrować nowy słuchacz, wystarczy dodać go do zestawu, a nawet jeśli nie zostanie usunięty jawnie, jeśli słuchacz nie będzie już odwoływany, zostanie automatycznie usunięty przez JVM.

 22
Author: icza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-11 11:53:34

Ten wpis na blogu demonstruje użycie obu klas: Java: synchronizing on an ID . Użycie idzie mniej więcej tak:

private static IdMutexProvider MUTEX_PROVIDER = new IdMutexProvider();

public void performTask(String resourceId) {
    IdMutexProvider.Mutex mutext = MUTEX_PROVIDER.getMutex(resourceId);
    synchronized (mutext) {
        // look up the resource and do something with it
    }
}

IdMutextProvider udostępnia obiekty oparte na identyfikatorach do synchronizacji. Wymagania są następujące:

  • musi zwrócić odwołanie do tego samego obiektu w celu jednoczesnego użycia równoważnych identyfikatorów
  • musi zwrócić inny obiekt dla różnych identyfikatorów
  • Brak mechanizmu zwalniania (obiekty nie są zwracane do dostawcy)
  • nie może wyciekać (nieużywane obiekty kwalifikują się do zbierania śmieci)

Uzyskuje się to za pomocą mapy pamięci wewnętrznej typu:

WeakHashMap<Mutex, WeakReference<Mutex>>

Obiekt jest zarówno kluczem, jak i wartością. Gdy nic poza mapą nie ma twardego odniesienia do obiektu, może być zbierane śmieci. Wartości na mapie są przechowywane z twardymi referencjami, więc wartość musi być zawinięta w WeakReference, aby zapobiec wyciekowi pamięci. Ten ostatni punkt jest omówiony w javadoc .

 5
Author: McDowell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 22:05:10

Jeśli na przykład chcesz śledzić wszystkie obiekty utworzone z określonej klasy. Aby te obiekty nadal mogły być zbierane jako śmieci, zachowujesz listę / mapę słabych odniesień do obiektów zamiast samych obiektów.

Teraz, jeśli ktoś mógłby mi wyjaśnić phantom-odniesienia do mnie, byłbym szczęśliwy...

 3
Author: JesperE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 20:05:13

Jak wspomniano powyżej, słabe odniesienia są utrzymywane tak długo, jak istnieje silne odniesienie.

Przykładowym zastosowaniem byłoby użycie WeakReference wewnątrz słuchaczy, tak aby słuchacze nie byli aktywni po zniknięciu głównego odniesienia do ich obiektu docelowego. Zauważ, że nie oznacza to, że słaba Referencja jest usuwana z listy słuchaczy, sprzątanie jest nadal wymagane, ale może być wykonywane na przykład w zaplanowanych godzinach. Ma to również wpływ na zapobieganie obiekt słuchany od posiadania silnych odniesień i ostatecznie być źródłem pamięci wzdęcia. Przykład: komponenty Swing GUI odnoszące się do modelu o dłuższym cyklu życia niż okno.

Podczas zabawy ze słuchaczami, jak opisano powyżej, szybko zdaliśmy sobie sprawę, że przedmioty są zbierane "natychmiast" z punktu widzenia użytkownika.

 3
Author: Louis Jacomet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-18 18:52:46

Jednym z prawdziwych zastosowań, jakie miałem dla słabych stron, jest to, że masz pojedynczy, bardzo duży obiekt, który jest rzadko używany. Nie chcesz trzymać go w pamięci, gdy nie jest potrzebny; ale jeśli inny wątek potrzebuje tego samego obiektu, nie chcesz też mieć dwóch z nich w pamięci. Możesz zachować 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.

 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 20:09:36

Zrobiłem wyszukiwanie kodu google dla "new WeakHashMap()".

Mam kilka dopasowań z projektu GNU classpath i

  1. Apache Xbean Project: WeakHashMapEditor.java
  2. Apache Lucene project: CachingWrapperFilter.java
 1
Author: anjanb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-07 17:33:57

Możesz użyć weakhashmap do zaimplementowania buforowania bez zasobów do tworzenia ekspansywnych obiektów.

Ale zauważ, że nie jest pożądane posiadanie mutowalnych 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.

 -1
Author: Andreas Petersson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 20:28:42