Kann jemand den Unterschied zwischen den drei Referenzklassen erklären (oder einen Link zu einer netten Erklärung posten)? SoftReference
> WeakReference
> PhantomReference
, Aber wenn ich würde alle nutzen? Warum gibt es ein WeakHashMap
aber nein SoftHashMap
oder PhantomHashMap
?
Und wenn ich den folgenden Code verwende ...
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?!
}
...was geschieht? Muss ich ref
vor jeder Anweisung überprüfen, ob null ist (dies ist falsch, aber was soll ich tun)? Entschuldigung für die Schnellfeuerfragen, aber ich habe Probleme, diese Reference
Klassen zu verstehen ... Danke!
java
reference
weak-references
phantom-reference
soft-references
Haywood Jablomey
quelle
quelle
WeakHashMap
aber keineSoftHashMap
oderPhantomHashMap
ausgezeichnete Frage, warum habe ich das vorher nicht bemerkt .. ??ref != null
Prüfung macht keinen Sinn.ref
wird niemals seinnull
.strongRef --> weakRef --> objA
. Jetzt wirdobjA
GCed oder nicht, da es einen indirekten Verweis von hatstrongRef
.Antworten:
Die Java-Bibliotheksdokumentation für das
java.lang.ref
Paket kennzeichnet die abnehmende Stärke der drei expliziten Referenztypen.Sie verwenden a,
SoftReference
wenn das referenzierte Objekt so lange am Leben bleiben soll, bis der Host-Prozess fast keinen Speicher mehr hat. Das Objekt kann erst gesammelt werden, wenn der Kollektor Speicher freigeben muss . Locker gesagt, einSoftReference
Mittel binden , "Pin das Objekt, bis Sie nicht mehr können."Verwenden
WeakReference
Sie im Gegensatz dazu a, wenn Sie die Lebensdauer des referenzierten Objekts nicht beeinflussen möchten. Sie möchten lediglich eine separate Aussage über das referenzierte Objekt machen, solange es am Leben bleibt. Die Berechtigung des Objekts zur Sammlung wird nicht durch das Vorhandensein gebundenerWeakReference
s beeinflusst. So etwas wie eine externe Zuordnung von der Objektinstanz zu einer verwandten Eigenschaft, bei der die Eigenschaft nur aufgezeichnet werden muss, solange das verwandte Objekt lebt, ist eine gute Verwendung fürWeakReference
s undWeakHashMap
.Der letzte
PhantomReference
ist schwerer zu charakterisieren. EineWeakReference
solche Bindung hatPhantomReference
keinen Einfluss auf die Lebensdauer des referenzierten Objekts. Aber im Gegensatz zu den anderen Referenztypen kann man a nicht einmal dereferenzierenPhantomReference
. In gewissem Sinne zeigt es nicht auf das, worauf es zeigt, soweit Anrufer dies beurteilen können. Es ermöglicht lediglich das Verknüpfen einiger verwandter Daten mit dem referenzierten Objekt - Daten, die später überprüft und bearbeitet werden können, wenn das ObjektPhantomReference
in der zugehörigen Warteschlange in die Warteschlange gestellt wirdReferenceQueue
. Normalerweise leitet man einen Typ vonPhantomReference
diesem abgeleiteten Typ ab und enthält einige zusätzliche Daten. Leider ist ein Downcasting erforderlich, um einen solchen abgeleiteten Typ zu verwenden.In Ihrem Beispielcode kann nicht die
ref
Referenz (oder, wenn Sie es vorziehen, "Variable") null sein. Es ist vielmehr der Wert, der durch Aufrufen erhalten wirdReference#get()
, der null sein kann. Wenn sich herausstellt, dass es null ist, sind Sie zu spät. Das referenzierte Objekt ist bereits auf dem Weg, gesammelt zu werden:final String val = ref.get(); if (null != val) { // "val" is now pinned strongly. } else { // "val" is already ready to be collected. }
quelle
strongRef --> weakRef --> objA
. Jetzt wirdobjA
GCed oder nicht, da es einen indirekten Verweis von hatstrongRef
.objA
als Müll gesammelt werden . Das Anheften einesWeakReference
Objekts übt keinen Einfluss auf das Objekt aus, auf das diesesWeakReference
zeigt.objA
Müll gesammelt wird, muss die schwache Referenz zuerst rechts entfernt werden. Und eine starke Referenz weist auf die schwache Referenz hin, die es dem schwachen SchiedsrichterWeakReference
muss nicht abgeholt werden, damitobjA
es abgeholt werden kann. DasWeakReference
hält nichtobjA
am Leben. Es ist vielmehr eine Möglichkeit zu finden,objA
während es lebt - ohne diese Lebensdauer zu beeinflussen - und zu erkennen, wann der Sammler es bereits weggenommen hat.Ein Link: https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
PhantomHashMap
würde nicht sehr gut funktionieren, daget
immernull
für Phantomreferenzen zurückgegeben wird.Caches sind schwierig und
SoftHashMap
funktionieren möglicherweise nicht so gut, wie Sie vielleicht denken. Ich glaube jedoch, dass die Sammlungsbibliothek von Google eine allgemeine Referenzkartenimplementierung enthält.Sie sollten immer überprüfen, ob
get
nicht zurückgegeben wirdnull
. (Beachten Sie, dass nicht überprüft wird, ob dieReference
Referenz selbst nicht ... istnull
.) Bei internierten Zeichenfolgen wird dies immer der Fall sein, aber (wie immer) versuchen Sie nicht, "klug" zu sein.quelle
strongRef --> weakRef --> objA
. Jetzt wirdobjA
GCed oder nicht, da es einen indirekten Verweis von hatstrongRef
.Es sollte auch erwähnt werden, wie im Kommentar von Truong Xuan Tinh angegeben, hier: http://blog.yohanliyanage.com/2010/10/ktjs-3-soft-weak-phantom-references/
Diese JRockit-JVM implementiert schwache / weiche / Phantom-Referenzen anders als Sun JVM.
quelle
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()); }
In diesem Fall wird null ausgegeben. Der Aufruf an
System.gc()
ist hier wichtig.quelle