Czy ktoś może wyjaśnić różnicę między trzema klasami odniesienia (lub zamieścić link do ładnego wyjaśnienia)? SoftReference
> WeakReference
> PhantomReference
, Ale kiedy użyłbym każdy? Dlaczego jest, WeakHashMap
ale nie ma SoftHashMap
lub PhantomHashMap
?
A jeśli użyję następującego kodu ...
WeakReference<String> ref = new WeakReference<String>("Hello!");
if (ref != null) { // ref can get collected at any time...
System.gc(); // Let's assume ref gets collected here.
System.out.println(ref.get()); // Now what?!
}
...co się dzieje? Muszę sprawdzić, czy ref
jest null przed każdym rachunku (to jest złe, ale co należy zrobić)? Przepraszam za szybkie pytania, ale mam problem ze zrozumieniem tych Reference
zajęć ... Dzięki!
java
reference
weak-references
phantom-reference
soft-references
Haywood Jablomey
źródło
źródło
WeakHashMap
ale nieSoftHashMap
lubPhantomHashMap
doskonałe, dlaczego wcześniej tego nie zauważyłem .. ??ref != null
Czek nie ma sensu.ref
nigdy nie będzienull
.strongRef --> weakRef --> objA
. Teraz będzieobjA
GCed lub nie, ponieważ ma pośredni odnośnikstrongRef
.Odpowiedzi:
Dokumentacja biblioteki Java dla
java.lang.ref
pakietu charakteryzuje malejącą siłę trzech jawnych typów odwołań.Używasz a,
SoftReference
gdy chcesz, aby obiekt, do którego istnieje odwołanie, pozostał aktywny, dopóki proces hosta nie będzie zabrakło pamięci. Obiekt nie będzie kwalifikował się do kolekcji aż kolektor potrzebuje do wolnej pamięci. Luźno sformułowane, wiązanieSoftReference
oznacza: „Przypnij obiekt, dopóki nie będziesz mógł”.Z drugiej strony, użyj a,
WeakReference
gdy nie chcesz wpływać na czas życia obiektu, do którego się odwołuje; chcesz po prostu zrobić oddzielne stwierdzenie dotyczące obiektu, do którego się odwołujesz, dopóki pozostaje on żywy. Na kwalifikowalność obiektu do odbioru nie ma wpływu obecność związanych elementówWeakReference
. Coś w rodzaju zewnętrznego mapowania z instancji obiektu na powiązaną właściwość, gdzie właściwość musi być rejestrowana tylko tak długo, jak powiązany obiekt żyje, jest dobrym zastosowaniem dlaWeakReference
s iWeakHashMap
.Ten ostatni… -
PhantomReference
jest trudniejszy do scharakteryzowania. NaWeakReference
przykład takie ograniczeniePhantomReference
nie ma wpływu na żywotność obiektu, do którego się odwołuje. Ale w przeciwieństwie do innych typów referencyjnych, nie można nawet wyłuskać aPhantomReference
. W pewnym sensie nie wskazuje na to, na co wskazuje, o ile dzwoniący mogą powiedzieć. Pozwala tylko na powiązanie pewnych powiązanych danych z obiektem, do którego się odwołuje - danymi, które mogą być później sprawdzane i wykonywane, gdy zostanąPhantomReference
umieszczone w kolejce w powiązanych z nimi obiektachReferenceQueue
. Zwykle typ pochodzi zPhantomReference
tego typu pochodnego i zawiera dodatkowe dane. Niestety, użycie takiego typu pochodnego wymaga pewnych ograniczeń.W Twoim przykładowym kodzie to nie
ref
odwołanie (lub, jeśli wolisz, „zmienna”), które może mieć wartość null. Jest to raczej wartość uzyskana przez wywołanie,Reference#get()
która może być zerowa. Jeśli okaże się, że jest zerowy, jesteś za późno; obiekt, do którego istnieje odwołanie, jest już w drodze do pobrania:final String val = ref.get(); if (null != val) { // "val" is now pinned strongly. } else { // "val" is already ready to be collected. }
źródło
strongRef --> weakRef --> objA
. Teraz będzieobjA
GCed lub nie, ponieważ ma pośredni odnośnikstrongRef
.objA
kwalifikuje się do zbierania jako śmieci. PrzypięcieWeakReference
nie ma wpływu na obiekt, na któryWeakReference
wskazuje.objA
aby plik został wyrzucony jako śmieci, słabe odniesienie musi zostać najpierw usunięte po prawej stronie. Silne odniesienie wskazuje na słabe odniesienie, które sprawia, że słaby ref nie kwalifikuje się do GCedWeakReference
nie trzeba ich odbierać, aby umożliwićobjA
ich pobranie.WeakReference
Nie zachowaćobjA
przy życiu. Jest to raczej sposób na odnalezienieobjA
go za życia - bez wpływania na to życie - i wykrycie, kiedy kolekcjoner już go zabrał.Link: https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
PhantomHashMap
nie działałby zbyt dobrze, ponieważget
zawsze wracanull
do odniesień fantomowych.Pamięć podręczna jest trudna, więc
SoftHashMap
może nie działać tak dobrze, jak mogłoby się wydawać. Uważam jednak, że biblioteka kolekcji Google zawiera ogólną implementację mapy referencyjnej.Powinieneś zawsze sprawdzić, czy
get
zwraca non-null
. (Zwróć uwagę, że nie sprawdzanie, czyReference
samo odwołanie nie jest…null
). W przypadku łańcuchów z internowanymi ciągami tak będzie zawsze, ale (jak zawsze) nie staraj się być „sprytny”.źródło
strongRef --> weakRef --> objA
. Teraz będzieobjA
GCed lub nie, ponieważ ma pośredni odnośnikstrongRef
.Należy również wspomnieć, jak stwierdził w komentarzu Truong Xuan Tinh, tutaj: http://blog.yohanliyanage.com/2010/10/ktjs-3-soft-weak-phantom-references/
Ta JRockit JVM implementuje słabe / miękkie / fantomowe odniesienia inaczej niż Sun JVM.
źródło
String str = new String("hello, world"); WeakReference<String> ref = new WeakReference<String>(str); str = null; if (ref != null) { System.gc(); System.out.println(ref.get()); }
W takim przypadku zwróci wartość null. Wezwanie
System.gc()
jest tutaj ważne.źródło