Was ist der Unterschied zwischen java.lang.ref.WeakReference
y java.lang.ref.SoftReference
?
Antworten
Zu viele Anzeigen?De Schwache Referenzen verstehen von Ethan Nicholas:
Schwache Referenzen
A schwache Referenz ist, einfach ausgedrückt, ein Referenz, die nicht stark genug ist, um ein Objekt zu zwingen, im Speicher zu bleiben. Schwache Referenzen ermöglichen es Ihnen, die die Fähigkeit des Garbage Collectors, die Erreichbarkeit für Sie zu bestimmen, so dass Sie müssen das nicht selbst tun. Sie erstellen eine schwache Referenz wie folgt:
WeakReference weakWidget = new WeakReference(widget);
und dann an anderer Stelle des Codes können Sie verwenden
weakWidget.get()
um die aktuelleWidget
Objekt. Natürlich ist die schwache Referenz nicht stark genug ist, um Garbage Collection zu verhindern, also kann man finden (wenn es keine starken Referenzen auf das Widget gibt), dassweakWidget.get()
beginnt plötzlich zurückzukehren.null
....
Weiche Referenzen
A Soft-Referenz ist genau wie ein schwache Referenz, nur dass sie weniger das Objekt, auf das sie verweist, weniger eifrig auf das sie verweist. Ein Objekt, das nur schwach erreicht werden kann (die stärksten Referenzen auf es sind
WeakReferences
) wird beim nächsten Garbage Collection-Zyklus verworfen Sammelzyklus verworfen, aber ein Objekt, das sanft erreichbar ist, wird im Allgemeinen für eine Weile bleiben.
SoftReferences
sind nicht erforderlich auf sich anders zu verhalten alsWeakReferences
aber in der Praxis weich erreichbare Objekte sind im Allgemeinen so lange beibehalten, wie der Speicher reichlich vorhanden ist. Das macht sie zu einer ausgezeichnete Grundlage für einen Cache, wie wie den oben beschriebenen Bild-Cache, denn Sie können dem Garbage Garbage Collector kümmern kann, sowohl wie die Objekte erreichbar sind (ein stark erreichbares Objekt wird niemals entfernt werden aus dem Cache) und wie dringend er den den Speicher, den sie verbrauchen.
Und Peter Kessler fügte in einem Kommentar hinzu:
Die Sun JRE behandelt SoftReferences anders als WeakReferences. Wir versuchen, ein Objekt, das von einer SoftReference referenziert wird, zu behalten, wenn der verfügbare Speicher nicht überlastet ist. Ein Detail: Die Richtlinien für die JREs "-client" und "-server" sind unterschiedlich: Die JRE "-client" versucht, Ihren Fußabdruck klein zu halten, indem sie SoftReferences eher löscht als den Heap zu erweitern, während die JRE "-server" versucht, Ihre Leistung hoch zu halten, indem sie den Heap (wenn möglich) eher erweitert als SoftReferences zu löschen. Eine Größe passt nicht für alle.
Schwache Referenzen werden eifrig gesammelt. Wenn GC feststellt, dass ein Objekt schwach erreichbar ist (nur durch schwache Referenzen erreichbar), löscht er die schwachen Referenzen auf dieses Objekt sofort. Als solche sind sie gut geeignet für eine Referenz auf ein Objekt zu halten, für das Ihr Programm auch (stark referenzierte) "assoziierte Informationen" irgendwo aufbewahrt, wie z.B. zwischengespeicherte Reflection-Informationen über eine Klasse oder einen Wrapper für ein Objekt, etc. Alles, was keinen Sinn macht, nachdem das Objekt, mit dem es verbunden ist GC-ed ist. Wenn die schwache Referenz gelöscht wird, wird sie in eine Referenz-Warteschlange eingereiht, die Ihr Code irgendwo abruft, und verwirft die verknüpften Objekte ebenfalls. Das heißt, Sie behalten zusätzliche Informationen über ein Objekt, aber diese Informationen werden nicht mehr benötigt, sobald das Objekt, auf das sie verweisen verschwindet. In bestimmten Situationen können Sie sogar die Unterklasse WeakReference unterordnen und die zugehörigen Zusatzinformationen über das Objekt in den Feldern der Unterklasse WeakReference speichern. Eine weitere typische Verwendung von WeakReference ist in Verbindung mit Maps zur Aufbewahrung kanonischer Instanzen.
SoftReferences hingegen eignen sich für die Zwischenspeicherung externer, wiederherstellbarer Ressourcen da die GC in der Regel deren Löschung verzögert. Es ist jedoch garantiert, dass alle SoftReferences geleert werden, bevor OutOfMemoryError ausgelöst wird, so dass sie theoretisch keinen OOME[*] verursachen können.
Ein typischer Anwendungsfall ist die Aufbewahrung einer geparsten Form eines Inhalts aus einer Datei. Man würde ein System implementieren, bei dem man eine Datei lädt, sie parst und eine SoftReference auf das Root-Objekt der geparsten Darstellung. Das nächste Mal Sie die Datei benötigen, versuchen Sie, sie über die SoftReference abzurufen. Wenn Sie sie abrufen können, haben Sie sich ein weiteres Laden/Parsen erspart, und wenn die GC sie in der Zwischenzeit gelöscht hat, laden Sie sie neu. Auf diese Weise nutzen Sie den freien Speicher zur Leistungsoptimierung, riskieren aber kein OOME.
Und nun der [*]. Die Beibehaltung einer SoftReference kann an sich keinen OOME verursachen. Wenn Sie hingegen fälschlicherweise eine SoftReference für eine Aufgabe verwenden, für die eine WeakReference gedacht ist verwendet werden soll (d.h. Sie behalten Informationen, die mit einem Objekt irgendwie stark referenziert, und verwerfen sie, wenn das Referenzobjekt gelöscht wird gelöscht wird), können Sie auf OOME stoßen, wenn Ihr Code, der die ReferenceQueue abfragt abfragt und die zugehörigen Objekte verwirft, möglicherweise nicht zeitnah Weise ausgeführt wird.
Die Entscheidung hängt also von der Nutzung ab - Wenn Sie Informationen zwischenspeichern wollen, die teuer zu erstellen sind, aber aber dennoch aus anderen Daten rekonstruierbar sind, verwenden Sie Soft-Referenzen - wenn Sie einen Verweis auf eine kanonische Instanz von Daten aufbewahren, oder Sie einen Verweis auf ein Objekt haben wollen, ohne es zu "besitzen" (wodurch verhindern, dass es GC'd wird), verwenden Sie eine schwache Referenz.
In Java In der Reihenfolge vom Stärksten zum Schwächsten gibt es: Stark, Weich, Schwach und Phantom
A Starke Referenz ist ein normaler Verweis, der das verwiesene Objekt vor der Sammlung durch GC schützt, d.h. es wird nie garbage collects.
A Weiche Referenz für die Sammlung durch den Garbage Collector in Frage kommt, aber wahrscheinlich erst dann gesammelt wird, wenn der Speicher benötigt wird, d.h. Garbage Collects vor OutOfMemoryError
.
A Schwache Referenz ist eine Referenz, die ein referenziertes Objekt nicht vor der Sammlung durch GC schützt, d.h. Garbage Collects, wenn keine Strong oder Soft Refs vorhanden sind.
A Phantom-Referenz ist ein Verweis auf ein Objekt, auf das phantomweise verwiesen wird, nachdem es abgeschlossen wurde, aber bevor der zugewiesene Speicher zurückgewonnen wurde.
Analogie: Angenommen, eine JVM ist ein Königreich, ein Objekt ist ein König des Königreichs und GC ist ein Angreifer des Königreichs, der versucht, den König (das Objekt) zu töten.
- Wenn König ist Stark kann GC ihn nicht töten.
- Wenn König ist Weich GC greift ihn an, aber der König regiert das Königreich mit Schutz, bis Ressourcen verfügbar sind.
- Wenn König ist Schwach GC greift ihn an, aber er regiert das Königreich ohne Schutz.
- Wenn König ist Phantom GC hat ihn bereits getötet, aber König ist über seine Seele verfügbar.
Schwache Referenz http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html
Das Prinzip: weak reference
steht im Zusammenhang mit der Garbage Collection. Normalerweise wird ein Objekt, das eine oder mehrere reference
kommen für die Müllabfuhr nicht in Frage.
Der oben genannte Grundsatz ist nicht anwendbar, wenn es sich um weak reference
. Wenn ein Objekt nur einen schwachen Bezug zu anderen Objekten hat, dann ist es bereit für die Garbage Collection.
Schauen wir uns das folgende Beispiel an: Wir haben eine Map
mit Objects, wobei Key eine Referenz auf ein Objekt ist.
import java.util.HashMap;
public class Test {
public static void main(String args[]) {
HashMap<Employee, EmployeeVal> aMap = new
HashMap<Employee, EmployeeVal>();
Employee emp = new Employee("Vinoth");
EmployeeVal val = new EmployeeVal("Programmer");
aMap.put(emp, val);
emp = null;
System.gc();
System.out.println("Size of Map" + aMap.size());
}
}
Nun haben wir während der Ausführung des Programms emp = null
. Die Map
das Halten des Schlüssels macht hier keinen Sinn, da es null
. In der obigen Situation wird das Objekt nicht in den Müll geworfen.
WeakHashMap
WeakHashMap
ist eine, bei der die Einträge ( key-to-value mappings
) werden entfernt, wenn es nicht mehr möglich ist, sie aus der Datenbank abzurufen. Map
.
Ich zeige das obige Beispiel auch mit WeakHashMap
import java.util.WeakHashMap;
public class Test {
public static void main(String args[]) {
WeakHashMap<Employee, EmployeeVal> aMap =
new WeakHashMap<Employee, EmployeeVal>();
Employee emp = new Employee("Vinoth");
EmployeeVal val = new EmployeeVal("Programmer");
aMap.put(emp, val);
emp = null;
System.gc();
int count = 0;
while (0 != aMap.size()) {
++count;
System.gc();
}
System.out.println("Took " + count
+ " calls to System.gc() to result in weakHashMap size of : "
+ aMap.size());
}
}
Ausgabe: Unter 20 calls to System.gc()
zum Ergebnis aMap size
von : 0.
WeakHashMap
hat nur schwache Verweise auf die Schlüssel, keine starken Verweise wie andere Map
Klassen. Es gibt Situationen, in denen man aufpassen muss, wenn der Wert oder Schlüssel stark referenziert ist, obwohl man WeakHashMap
. Dies kann vermieden werden, indem das Objekt in eine WeakReference .
import java.lang.ref.WeakReference;
import java.util.HashMap;
public class Test {
public static void main(String args[]) {
HashMap<Employee, EmployeeVal> map =
new HashMap<Employee, EmployeeVal>();
WeakReference<HashMap<Employee, EmployeeVal>> aMap =
new WeakReference<HashMap<Employee, EmployeeVal>>(
map);
map = null;
while (null != aMap.get()) {
aMap.get().put(new Employee("Vinoth"),
new EmployeeVal("Programmer"));
System.out.println("Size of aMap " + aMap.get().size());
System.gc();
}
System.out.println("Its garbage collected");
}
}
Weiche Referenzen.
Soft Reference
ist etwas stärker als die schwache Referenz. Soft-Referenz ermöglicht Garbage Collection, bittet aber den Garbage Collector, sie nur zu löschen, wenn es keine andere Möglichkeit gibt.
Der Garbage Collector sammelt weich erreichbare Objekte nicht aggressiv ein, so wie er es bei schwach erreichbaren Objekten tut - stattdessen sammelt er weich erreichbare Objekte nur ein, wenn er den Speicher wirklich "braucht". Soft-Referenzen sind eine Möglichkeit, dem Garbage Collector zu sagen: "Solange der Speicher nicht zu knapp ist, möchte ich dieses Objekt behalten. Aber wenn der Speicher wirklich knapp wird, dann sammeln Sie es ein und ich kümmere mich darum. Der Garbage Collector muss alle Soft-Referenzen löschen, bevor er OutOfMemoryError
.
- See previous answers
- Weitere Antworten anzeigen