Was ist der Unterschied zwischen java.lang.ref.WeakReference
und java.lang.ref.SoftReference
?
java
reference
weak-references
soft-references
driekken
quelle
quelle
Antworten:
Aus dem Verständnis schwacher Referenzen , von Ethan Nicholas:
Und Peter Kessler fügte in einem Kommentar hinzu:
quelle
Schwache Referenzen werden eifrig gesammelt. Wenn GC feststellt, dass ein Objekt schwach erreichbar ist (nur über schwache Referenzen erreichbar), werden die schwachen Referenzen auf dieses Objekt sofort gelöscht. Als solche eignen sie sich gut, um einen Verweis auf ein Objekt zu behalten, für das Ihr Programm auch irgendwo (stark referenzierte) "zugehörige Informationen" speichert, z. B. zwischengespeicherte Reflexionsinformationen über eine Klasse oder einen Wrapper für ein Objekt usw. Alles, was dazu beiträgt Es macht keinen Sinn, das Objekt zu behalten, dem es zugeordnet ist. Wenn die schwache Referenz gelöscht wird, wird sie in eine Referenzwarteschlange eingereiht, die Ihr Code irgendwo abfragt, und die zugehörigen Objekte werden ebenfalls verworfen. Das heißt, Sie behalten zusätzliche Informationen zu einem Objekt bei, aber diese Informationen werden nicht benötigt, sobald das Objekt, auf das es sich bezieht, verschwindet. Tatsächlich, In bestimmten Situationen können Sie sogar WeakReference unterordnen und die zugehörigen zusätzlichen Informationen zum Objekt in den Feldern der WeakReference-Unterklasse aufbewahren. Eine andere typische Verwendung von WeakReference ist die Verwendung von Maps zum Speichern kanonischer Instanzen.
SoftReferences hingegen eignen sich zum Zwischenspeichern externer, wiederherstellbarer Ressourcen, da der GC das Löschen normalerweise verzögert. Es ist jedoch garantiert, dass alle SoftReferences gelöscht werden, bevor OutOfMemoryError ausgelöst wird, sodass sie theoretisch kein OOME [*] verursachen können.
Ein typisches Anwendungsfallbeispiel ist das Beibehalten einer analysierten Form eines Inhalts aus einer Datei. Sie würden ein System implementieren, in dem Sie eine Datei laden, analysieren und eine SoftReference für das Stammobjekt der analysierten Darstellung beibehalten würden. Wenn Sie die Datei das nächste Mal benötigen, versuchen Sie, sie über die SoftReference abzurufen. Wenn Sie es abrufen können, haben Sie sich ein weiteres Laden / Parsen erspart, und wenn der GC es in der Zwischenzeit gelöscht hat, laden Sie es neu. Auf diese Weise nutzen Sie freien Speicher für die Leistungsoptimierung, riskieren jedoch kein OOME.
Nun zum [*]. Das Beibehalten einer SoftReference kann kein OOME an sich verursachen. Wenn Sie andererseits fälschlicherweise SoftReference für eine Aufgabe verwenden, für die eine WeakReference verwendet werden soll (dh Sie behalten die mit einem Objekt verknüpften Informationen bei, auf die irgendwie stark verwiesen wird, und verwerfen sie, wenn das Referenzobjekt gelöscht wird), können Sie auf OOME as stoßen Ihr Code, der die ReferenceQueue abfragt und die zugehörigen Objekte verwirft, wird möglicherweise nicht rechtzeitig ausgeführt.
Die Entscheidung hängt also von der Verwendung ab. Wenn Sie Informationen zwischenspeichern, deren Erstellung teuer ist, die jedoch aus anderen Daten rekonstruierbar sind, verwenden Sie weiche Verweise. Wenn Sie einen Verweis auf eine kanonische Instanz einiger Daten beibehalten oder dies möchten Verwenden Sie eine schwache Referenz, wenn Sie einen Verweis auf ein Objekt haben, ohne es zu "besitzen" (wodurch verhindert wird, dass es GC-fähig wird).
quelle
WeakReference
ist, dass an Orten, an denen man es verwenden sollte, die Tatsache, dass man nach dem Erlöschen des Verweises für eine Weile gültig bleiben kann, tolerierbar sein kann, aber nicht wünschenswert ist.WeakReference
, um GC-Läufe zu beobachten. Siehe Ausarbeitung: stackoverflow.com/a/46291143/632951In Java ; Reihenfolge vom stärksten zum schwächsten gibt es: Stark, Weich, Schwach und Phantom
Eine starke Referenz ist eine normale Referenz, die das referenzierte Objekt vor der Erfassung durch GC schützt. dh Niemals sammelt sich Müll.
Eine Soft-Referenz kann vom Garbage Collector erfasst werden, wird jedoch wahrscheinlich erst erfasst, wenn ihr Speicher benötigt wird. dh Müll sammelt sich vorher
OutOfMemoryError
.Eine schwache Referenz ist eine Referenz, die ein referenziertes Objekt nicht vor der Erfassung durch GC schützt. dh Müll sammelt sich, wenn keine starken oder weichen Refs vorhanden sind.
Ein Phantom Referenz ist eine Referenz auf ein Objekt wird phantomly verwiesen , nachdem er fertig gestellt wurde, aber vor dem zugewiesenen Speicher zurückgewonnen wurde.
Quelle
Analogie: Angenommen, eine JVM ist ein Königreich, Object ist ein König des Königreichs und GC ist ein Angreifer des Königreichs, der versucht, den König (Objekt) zu töten.
quelle
until memory is available
macht keinen Sinn. Meinst duis eligible for collection by garbage collector, but probably won't be collected until its memory is needed for another use
?Schwache Referenz http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html
Prinzip:
weak reference
bezieht sich auf die Speicherbereinigung. Normalerweise kann ein Objekt mit einem oder mehreren Objektenreference
nicht zur Speicherbereinigung verwendet werden.Das obige Prinzip ist nicht anwendbar, wenn es ist
weak reference
. Wenn ein Objekt nur eine schwache Referenz zu anderen Objekten hat, ist es für die Speicherbereinigung bereit.Schauen wir uns das folgende Beispiel an: Wir haben ein
Map
with Objects, bei dem Key auf ein Objekt verweist.Nun, während der Ausführung des Programms haben wir gemacht
emp = null
. DasMap
Halten des Schlüssels macht hier so wie es ist keinen Sinnnull
. In der obigen Situation wird das Objekt nicht durch Müll gesammelt.WeakHashMap
WeakHashMap
Inkey-to-value mappings
diesem Fall werden die Einträge ( ) entfernt, wenn sie nicht mehr von der abgerufen werden könnenMap
.Lassen Sie mich das obige Beispiel mit WeakHashMap zeigen
Ausgang: Nahm
20 calls to System.gc()
zu Folge inaMap size
der: 0.WeakHashMap
hat nur schwache Verweise auf die Schlüssel, keine starken Verweise wie andereMap
Klassen. Es gibt Situationen, auf die Sie achten müssen, wenn der Wert oder Schlüssel stark referenziert wird, obwohl Sie ihn verwendet habenWeakHashMap
. Dies kann vermieden werden, indem das Objekt in eine WeakReference eingeschlossen wird .Weiche Referenzen.
Soft Reference
ist etwas stärker als die schwache Referenz. Die weiche Referenz ermöglicht die Speicherbereinigung, bittet den Speicherbereiniger jedoch, sie nur zu löschen, wenn keine andere Option vorhanden ist.Der Garbage Collector sammelt nicht wie bei schwach erreichbaren Objekten aggressiv erreichbare Objekte aggressiv, sondern nur dann, wenn er den Speicher wirklich "benötigt". Weiche Referenzen sind eine Möglichkeit, dem Garbage Collector zu sagen: "Solange der Speicher nicht zu eng ist, möchte ich dieses Objekt behalten. Aber wenn der Speicher sehr knapp wird, sammeln Sie es und ich werde mich darum kümmern." damit." Der Garbage Collector muss alle weichen Referenzen löschen, bevor er werfen kann
OutOfMemoryError
.quelle
NullPointerException
in bekommenaMap.get().put(...)
.WeakHashMap
Beispiel (da dies das erste ist, das ein schwaches Verhalten zeigt). Suchen Sie im Dokument nach "WeakHashMap":"An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. "
Der gesamte Sinn der Verwendung von WeakHashMap besteht darin, dass Sie keine WeakReference deklarieren / übergeben müssen. Die WeakHashMap erledigt das intern für Sie. docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.htmlWeakHashMap
Aktion mit einer Beispiel-App, die zeigt, wie Einträge erst nach Ausführung der Garbage Collection entfernt werden, finden Sie unter Meine Antwort auf die Frage: Wächst die WeakHashMap ständig oder werden die Garbage Keys gelöscht? .Der einzige wirkliche Unterschied zwischen einer weichen Referenz und einer schwachen Referenz besteht darin, dass
quelle
SoftReference
ist für Caches konzipiert. Wenn festgestellt wird, dass einWeakReference
Objekt auf ein ansonsten nicht erreichbares Objekt verweist, wird es sofort gelöscht.SoftReference
kann so belassen werden wie es ist. In der Regel gibt es einen Algorithmus, der sich auf die Menge des freien Speichers und die zuletzt verwendete Zeit bezieht, um zu bestimmen, ob dieser gelöscht werden soll. Der aktuelle Sun-Algorithmus löscht die Referenz, wenn sie nicht in so vielen Sekunden verwendet wurde, wie auf dem Java-Heap Megabyte Speicher frei sind (konfigurierbar, Server-HotSpot prüft gegen den maximal möglichen Heap, wie von festgelegt-Xmx
).SoftReference
s wird gelöscht, bevorOutOfMemoryError
es geworfen wird, sofern nicht anders erreichbar.quelle
java.lang
. Ein solcher Missbrauch von Synonymen nützt niemandem etwas.Dieser Artikel kann sehr hilfreich sein, um starke, weiche, schwache und Phantomreferenzen zu verstehen.
Um Ihnen eine Zusammenfassung zu geben,
Wenn Sie nur schwache Verweise auf ein Objekt haben (ohne starke Verweise), wird das Objekt im nächsten GC-Zyklus von GC zurückgefordert.
Wenn Sie nur weiche Verweise auf ein Objekt haben (ohne starke Verweise), wird das Objekt von GC nur dann zurückgefordert, wenn JVM nicht mehr über genügend Speicher verfügt.
Man kann also sagen, dass starke Referenzen die ultimative Kraft haben (können von GC niemals gesammelt werden).
Weiche Referenzen sind leistungsfähiger als schwache Referenzen (da sie dem GC-Zyklus entgehen können, bis JVM nicht mehr über genügend Speicher verfügt).
Schwache Referenzen sind noch weniger leistungsfähig als weiche Referenzen (da sie keinen GC-Zyklus entziehen können und zurückgefordert werden, wenn das Objekt keine andere starke Referenz hat).
Restaurant Analogie
Wenn Sie ein starker Kunde sind (analog zu einer starken Referenz), werden Sie Ihren Tisch (den Speicherbereich auf dem Haufen) niemals verlassen, selbst wenn ein neuer Kunde ins Restaurant kommt oder was auch immer passiert. Der Kellner hat kein Recht, Ihnen zu sagen (oder Sie sogar zu bitten), das Restaurant zu verlassen.
Wenn Sie ein weicher Kunde sind (analog zur weichen Referenz), werden Sie vom Kellner nicht aufgefordert, den Tisch zu verlassen, wenn kein neuer Kunde in das Restaurant kommt, es sei denn, es ist kein anderer leerer Tisch mehr vorhanden, um den neuen Kunden aufzunehmen. (Mit anderen Worten, der Kellner fordert Sie auf, den Tisch nur zu verlassen, wenn ein neuer Kunde eintritt und für diesen neuen Kunden kein anderer Tisch mehr vorhanden ist.)
Wenn Sie ein schwacher Kunde sind (analog zu einer schwachen Referenz), kann der Kellner Sie nach seinem Willen (zu jedem Zeitpunkt) auffordern, das Restaurant zu verlassen: P.
quelle
Der einzige wirkliche Unterschied
Per doc , lose WeakReferences muss von einem laufenden GC gelöscht werden.
Per doc , lose SoftReferences muss vor OOM gelöscht werden ausgelöst.
Das ist der einzige wirkliche Unterschied. Alles andere ist nicht Vertragsbestandteil. (Ich gehe davon aus, dass die neuesten Dokumente vertraglich sind.)
SoftReferences sind nützlich. Speicherempfindliche Caches verwenden SoftReferences, keine WeakReferences.
Die einzig richtige Verwendung von WeakReference ist die Beobachtung des GC-Laufs. Dazu erstellen Sie eine neue WeakReference, deren Objekt sofort den Gültigkeitsbereich verlässt, und versuchen dann, null zu entfernen
weak_ref.get()
. Wenn dies dernull
Fall ist, erfahren Sie, dass der GC zwischen dieser Dauer ausgeführt wurde.Bei falscher Verwendung von WeakReference ist die Liste endlos:
Ein mieser Hack, um eine Prioritäts-2-Softreferenz so zu implementieren, dass Sie keine schreiben müssen, aber sie funktioniert nicht wie erwartet, da der Cache bei jedem GC-Lauf gelöscht wird, selbst wenn freier Speicher vorhanden ist. Phails finden Sie unter https://stackoverflow.com/a/3243242/632951 . (Außerdem, was ist, wenn Sie mehr als 2 Ebenen der Cache-Priorität benötigen? Sie müssten immer noch eine echte Bibliothek dafür benötigen.)
ein lausiger Hack zu assoziieren Daten mit einem Objekt einer vorhandenen Klasse, doch sie schafft ein Speicherleck (OutOfMemoryError) , wenn der GC eine Pause nach dem weakreferences geschaffen nehmen entscheidet. Außerdem ist es mehr als hässlich: Ein besserer Ansatz ist die Verwendung von Tupeln.
Ein mieser Hack, um Daten einem Objekt einer vorhandenen Klasse zuzuordnen, bei dem die Klasse den Nerv hat, sich selbst nicht unterklassifizierbar zu machen, und der in einem vorhandenen Funktionscode verwendet wird, den Sie aufrufen müssen. In einem solchen Fall besteht die richtige Lösung darin, entweder die Klasse zu bearbeiten und sie unterklassifizierbar zu machen oder die Funktion zu bearbeiten und eine Schnittstelle anstelle einer Klasse zu verwenden oder eine alternative Funktion zu verwenden.
quelle
equals()
nur die Objektidentität ist? Weiche Referenzen scheinen dort eine Verschwendung zu sein, denn sobald ein Schlüsselobjekt nicht mehr gut erreichbar ist, wird niemand mehr diese Zuordnung nachschlagen.Die sechs Arten von Objekterreichbarkeitszuständen in Java:
Für weitere Informationen: https://www.artima.com/insidejvm/ed2/gc16.html «Zusammenbruch
quelle
Man sollte sich bewusst sein, dass ein schwach referenziertes Objekt nur dann erfasst wird, wenn es NUR schwache Referenzen hat. Wenn es nur eine starke Referenz hat, wird es nicht gesammelt, egal wie viele schwache Referenzen es hat.
quelle
Um einen Aspekt der Speichernutzung in Aktion zu geben, habe ich ein Experiment mit starken, weichen, schwachen und Phantomreferenzen unter starker Last mit schweren Objekten durchgeführt, indem ich sie bis zum Ende des Programms beibehalten habe. Dann überwacht Heap - Nutzung & GC Verhalten . Diese Metriken können von Fall zu Fall variieren, bieten aber sicherlich ein hohes Verständnis. Nachfolgend finden Sie Ergebnisse.
Heap & GC Verhalten unter starker Last
Hier erhalten Sie detailliertere Grafiken, Statistiken und Beobachtungen für dieses Experiment .
quelle
WeakReference : Objekte, auf die nur schwach verwiesen wird, werden bei jedem GC-Zyklus (geringfügig oder vollständig) erfasst.
SoftReference : Wann Objekte erfasst werden, auf die nur sanft verwiesen wird, hängt ab von:
-XX: SoftRefLRUPolicyMSPerMB = N-Flag (Standardwert ist 1000, auch bekannt als 1 Sekunde)
Menge an freiem Speicher im Heap.
Beispiel:
Dann wird ein Objekt erfasst, auf das nur von SoftReference verwiesen wird, wenn der letzte Zugriff beim Zugriff länger als 10 Sekunden ist.
quelle