it-swarm.com.de

Was ist der Unterschied zwischen SoftReference und WeakReference in Java?

Was ist der Unterschied?

743
driekken

Aus nderstanding Weak References von Ethan Nicholas:

Schwache Referenzen

Eine schwache Referenz ist, einfach ausgedrückt, eine Referenz, die nicht stark genug ist, um ein Objekt dazu zu zwingen, im Speicher zu bleiben. Mit schwachen Referenzen können Sie die Fähigkeit des Garbage Collectors nutzen, die Erreichbarkeit für Sie zu bestimmen, sodass Sie dies nicht selbst tun müssen. Sie erstellen eine schwache Referenz wie folgt:

WeakReference weakWidget = new WeakReference(widget);

und dann an anderer Stelle im Code können Sie weakWidget.get() verwenden, um das aktuelle Widget -Objekt abzurufen. Natürlich ist die schwache Referenz nicht stark genug, um die Garbage Collection zu verhindern. Wenn also keine starken Verweise auf das Widget vorhanden sind, gibt weakWidget.get() plötzlich null zurück.

...

Weiche Referenzen

Eine weiche Referenz ist genau wie eine schwache Referenz, außer dass es weniger eifrig ist, das Objekt wegzuwerfen, auf das sie sich bezieht. Ein Objekt, das nur schwach erreichbar ist (die stärksten Verweise darauf sind WeakReferences), wird beim nächsten Garbage Collection-Zyklus verworfen, aber ein Objekt, das nur schwach erreichbar ist, bleibt im Allgemeinen eine Weile stehen.

SoftReferences ist nicht erforderlich , um sich anders zu verhalten als WeakReferences, aber in der Praxis bleiben weich erreichbare Objekte im Allgemeinen erhalten, solange genügend Speicher vorhanden ist. Dies macht sie zu einer hervorragenden Grundlage für einen Cache wie den oben beschriebenen Image-Cache, da Sie dem Garbage Collector die Möglichkeit geben können, sich um die Erreichbarkeit der Objekte zu kümmern (ein stark erreichbares Objekt wird niemals aus dem Cache entfernt werden) und wie dringend es den Speicher benötigt, den sie verbrauchen.

Und Peter Kessler hat in einem Kommentar hinzugefügt:

Die Sun JRE behandelt SoftReferences anders als WeakReferences. Wir versuchen, an Objekten festzuhalten, auf die von einer SoftReference verwiesen wird, wenn der verfügbare Speicher nicht unter Druck steht. Ein Detail: Die Richtlinien für die JREs "-client" und "-server" unterscheiden sich: Die JRE -client versucht, Ihren Footprint klein zu halten, indem sie lieber SoftReferences löscht, als den Heap zu erweitern, während die JRE -server versucht, Ihren zu halten hohe Leistung, indem Sie den Heap (wenn möglich) lieber erweitern als SoftReferences löschen. Eine Größe passt nicht allen.

887
Michael Myers

Schwache Referenzen werden eifrig gesammelt. Wenn GC feststellt, dass ein Objekt schwach erreichbar ist (nur durch schwache Verweise erreichbar), werden die schwachen Verweise auf dieses Objekt sofort gelöscht. Sie eignen sich daher gut dazu, Einen Verweis auf ein Objekt zu behalten, für das Ihr Programm auch (Stark referenzierte) "verknüpfte Informationen" enthält, z. B. zwischengespeicherte Reflektionsinformationen über eine Klasse oder einen Wrapper für ein Objekt usw. Alles, was keinen Sinn macht, nachdem das Objekt, mit dem es verbunden ist, zu behalten, ist GC-ed. Wenn die schwache Referenz gelöscht wird, wird sie in eine -Warteschlange eingereiht, die Ihr Code irgendwo abruft, und verwirft auch die zugehörigen -Objekte. Das heißt, Sie behalten zusätzliche Informationen zu einem Objekt, aber diese Informationen werden nicht benötigt, sobald das Objekt, auf das es verweist, verschwunden ist. In bestimmten Situationen können Sie sogar eine Unterklasse WeakReference definieren und die dazugehörigen zusätzlichen Informationen zum Objekt beibehalten in den Feldern der WeakReference-Unterklasse. Eine andere typische Verwendung von WeakReference ist in Verbindung mit Maps zur Aufbewahrung kanonischer Instanzen.

SoftReferences hingegen eignen sich zum Zwischenspeichern von externen, nachvollziehbaren Ressourcen Der GC verzögert normalerweise das Löschen dieser Ressourcen. Es wird jedoch garantiert, dass alle SoftReferences gelöscht werden, bevor OutOfMemoryError ausgelöst wird, sodass sie Theoretisch kein OOME [*] verursachen können.

Ein typisches Anwendungsbeispiel ist das Verwalten einer geparsten 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 Repräsentation beibehalten. 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 eine weitere Ladung/Analyse erspart, und wenn der GC .__ es in der Zwischenzeit gelöscht hat, laden Sie es erneut. Auf diese Weise nutzen Sie kostenlosen Speicher für die Leistungsoptimierung, riskieren aber kein OOME.

Nun zum [*]. Das Beibehalten einer SoftReference kann kein OOME in sich verursachen. Wenn Sie jedoch versehentlich SoftReference für eine Task verwenden, soll eine WeakReference verwendet werden (dh, Sie enthalten Informationen, die einem Objekt zugeordnet sind. (gelöscht)) können Sie OOME als Ihren Code ausführen, der die ReferenceQueue .__ abruft und verwirft, dass die zugehörigen Objekte möglicherweise nicht rechtzeitig ausgeführt werden.

Die Entscheidung hängt also von der Verwendung ab - Wenn Sie Informationen zwischenspeichern, deren Aufbau zwar teuer ist, aber Aus anderen Daten rekonstruierbar ist, verwenden Sie weiche Verweise -, wenn Sie einen Verweis auf ein kanonisches Element beibehalten Beispiel für einige Daten, oderWenn Sie einen Verweis auf ein Objekt haben möchten, ohne es zu "besitzen" (dh zu verhindern, dass es GC ist), verwenden Sie einen schwachen Verweis.

194
driekken

In Java; Reihenfolge von stärksten zu 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. Niemals Müll sammelt. 

Ein Soft reference kann vom Garbage Collector abgerufen werden, wird aber wahrscheinlich nicht erfasst, bis der Speicher benötigt wird. d. h. Müll sammelt sich vor OutOfMemoryError

Ein Weak reference ist eine Referenz, die ein referenziertes Objekt nicht vor der Erfassung durch GC schützt. d. h. Müll sammelt sich, wenn keine starken oder weichen Verweise vorliegen. 

Ein Phantomverweis ist ein Verweis auf ein Objekt, das phantomisch referenziert wird, nachdem es abgeschlossen wurde, aber bevor der zugewiesene Speicher freigegeben wurde.

Quelle

Analogie: Nehmen wir an, 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 zu töten (Objekt).

  • Wenn King Strong ist, kann GC ihn nicht töten. 
  • Wenn King Soft ist, greift GC ihn an, aber King regiert das Königreich mit Schutz, bis Ressourcen verfügbar sind. 
  • Wenn King Weak ist, greift GC ihn an, aber er regiert das Königreich ohne Schutz. 
  • Wenn der König Phantom ist, hat GC ihn bereits getötet, aber der König ist über seine Seele verfügbar.
119
Premraj

Schwache Referenzhttp://docs.Oracle.com/javase/1.5.0/docs/api/Java/lang/ref/WeakReference.html

Prinzip:weak reference bezieht sich auf die Garbage Collection. Normalerweise ist ein Objekt mit einer oder mehreren reference nicht für die Garbage Collection geeignet.
Das obige Prinzip ist nicht anwendbar, wenn es weak reference ist. Wenn ein Objekt nur einen schwachen Verweis auf andere Objekte hat, ist es für die Garbage Collection bereit.

Schauen wir uns das Beispiel unten an: Wir haben eine Map mit Objekten, wobei Key ein Objekt referenziert. 

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 gemacht. Das Map, das die Taste hält, macht hier keinen Sinn, da es null ist. In der obigen Situation wird das Objekt nicht als Müll gesammelt. 

WeakHashMap

Bei WeakHashMap werden die Einträge (key-to-value mappings) entfernt, wenn es nicht mehr möglich ist, sie aus der Map abzurufen.

Lassen Sie mich das obige Beispiel auch mit WeakHashMap zeigen.

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: Tone 20 calls to System.gc(), um aMap size von: 0 zu erhalten. 

WeakHashMap hat nur schwache Verweise auf die Schlüssel, keine starken Verweise wie andere Map-Klassen. Es gibt Situationen, in denen Sie aufpassen müssen, wenn auf den Wert oder Schlüssel stark verwiesen wird, obwohl Sie WeakHashMap verwendet haben. Dies kann vermieden werden, indem das Objekt in eine WeakReference eingeschlossen wird.

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. Die Softreferenz erlaubt die Speicherbereinigung, fordert den Speicherbereiniger jedoch auf, diese nur dann zu löschen, wenn keine andere Option vorhanden ist. 

Der Garbage Collector sammelt weich erreichbare Objekte nicht aggressiv auf die Weise, wie dies bei schwach erreichbaren Objekten der Fall ist, sondern sammelt weich erreichbare Objekte nur, wenn er den Speicher wirklich "benötigt". Weiche Verweise sind eine Möglichkeit, dem Müllsammler zu sagen: "Solange das Gedächtnis nicht zu knapp ist, möchte ich dieses Objekt behalten. Wenn das Gedächtnis jedoch sehr knapp wird, sammeln Sie es ab und ich kümmere mich darum damit." Der Garbage Collector muss alle weichen Referenzen löschen, bevor OutOfMemoryError ausgelöst werden kann.

68
Thalaivar

Der einzige wirkliche Unterschied zwischen einer weichen Referenz und einer schwachen Referenz besteht darin 

der Speicherbereiniger verwendet Algorithmen, um zu entscheiden, ob Ein weich erreichbares Objekt zurückfordern, aber ein schwach zurückfordern erreichbares Objekt.

45

SoftReference ist für Caches gedacht. Wenn festgestellt wird, dass eine WeakReference auf ein ansonsten nicht erreichbares Objekt verweist, wird es sofort gelöscht. SoftReference kann so belassen werden, wie sie ist. Typischerweise gibt es einen Algorithmus, der sich auf die Menge des freien Speichers und die Zeit bezieht, die zuletzt verwendet wurde, um zu bestimmen, ob er gelöscht werden soll. Der aktuelle Sun-Algorithmus löscht den Verweis, wenn er nicht innerhalb von Sekunden verwendet wurde, da auf dem Java-Heapspeicher Megabyte Speicher frei sind (konfigurierbar, der Server-HotSpot prüft den maximal möglichen Heap, wie von -Xmx festgelegt). SoftReferences wird gelöscht, bevor OutOfMemoryError geworfen wird, sofern nicht anders erreichbar.

22

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 über soft-Referenzen auf ein Objekt verfügen (ohne starke Referenzen), wird das Objekt von GC erst dann zurückgefordert, wenn der Speicher der JVM nicht ausreicht.


Sie können also sagen, dass starke Referenzen ultimative Macht (können niemals von GC gesammelt werden)

Weiche Verweise sind leistungsstark als schwache Verweise (da sie den GC-Zyklus umgehen können, bis die JVM nicht mehr über genügend Arbeitsspeicher verfügt).

Schwache Referenzen sind noch weniger leistungsfähig als weiche Referenzen (da sie keinen GC-Zyklus ausschließen können und werden zurückgefordert, wenn das Objekt keine anderen starken Referenzen hat).


Restaurant-Analogie

  • Kellner - GC 
  • Sie - Objekt in Haufen 
  • Restaurantbereich/Raum - Haufenplatz
  • Neuer Kunde - Neues Objekt, das einen Tisch im Restaurant haben möchte

Wenn Sie nun ein starker Kunde (analog zu einer starken Referenz) sind, werden Sie Ihren Tisch (den Speicherbereich auf dem Heap) nie verlassen, auch wenn ein neuer Kunde in das Restaurant kommt oder was auch immer passiert. Der Kellner hat kein Recht, Ihnen das Verlassen des Restaurants mitzuteilen (oder sogar zu verlangen).

Wenn Sie ein weicher Kunde (analog zu einer weichen Referenz) sind, wird der Kellner Sie, falls ein neuer Kunde in das Restaurant kommt, nicht zum Verlassen des Tisches auffordern, es sei denn, es ist kein leerer Tisch für das Restaurant vorhanden Neukunde. (Mit anderen Worten: Der Kellner fordert Sie auf, den Tisch nur dann zu verlassen, wenn ein neuer Kunde eingeht und für diesen neuen Kunden kein weiterer Tisch übrig ist.)

Wenn Sie ein schwacher Kunde (analog zu einer schwachen Referenz) sind, kann der Kellner Sie nach Belieben (jederzeit) bitten, das Restaurant zu verlassen: P

4
Lavish Kothari

Die sechs Arten der Erreichbarkeit von Objekten werden in Java -

  1. Starke erreichbare Objekte - GC sammelt nicht ( den von ) dieser Art von Objekten belegten Speicher zurückfordern. Diese sind über einen Wurzelknoten oder ein anderes stark erreichbares Objekt erreichbar (d. H. Über lokale Variablen, Klassenvariablen, Instanzvariablen usw.)
  2. Weiche erreichbare Objekte - GC versucht möglicherweise , diese Art von Objekten zu sammeln je nach speicherkonflikt. Diese sind von der Wurzel aus über ein oder mehrere Soft-Referenzobjekte erreichbar.
  3. Schwach erreichbare Objekte - GC muss diese Art von Objekten sammeln. Diese sind von der Wurzel aus über ein oder mehrere schwache Referenzobjekte erreichbar
  4. Auferstehbare Objekte - GC sammelt diese Objekte bereits. Aber sie können durch die Ausführung eines Finalizers zu einem der Zustände zurückkehren - Stark/Weich/Schwach
  5. Phantom erreichbares Objekt - GC sammelt diese Objekte bereits und hat festgestellt, dass sie nicht wiederauferstehen. Kann von jedem Finalizer ausgeführt werden (wenn er selbst eine finalize () -Methode deklariert, wurde der Finalizer ausgeführt) . Diese sind von der Wurzel aus über ein oder mehrere Phantomreferenzobjekte erreichbar
  6. Nicht erreichbares Objekt - Ein Objekt ist weder stark, leise, schwach noch durch ein Phantom erreichbar und kann nicht wiederbelebt werden. Diese Objekte können wiederhergestellt werden

Für weitere Informationen: https://www.artima.com/insidejvm/ed2/gc16.html "Einklappen

3
V.Vidyasagar

Um einen Aspekt der Speichernutzung in Aktion zu vermitteln, habe ich ein Experiment mit starken, weichen, schwachen und Phantomreferenzen unter hoher 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 mit Sicherheit ein umfassendes Verständnis. Nachstehend sind die Ergebnisse aufgeführt.

Heap & GC-Verhalten unter hoher Last

  • Starke/harte Referenz - Im weiteren Verlauf des Programms konnte JVM kein beibehaltenes stark referenziertes Objekt erfassen. Endete schließlich in "Java.lang.OutOfMemoryError: Java Heap Space"
  • Soft Reference - Während das Programm fortfuhr, nahm die Heap-Nutzung weiter zu, aber die GC der ALTEN Generation geschah, als sie sich dem maximalen Heap näherte. GC startet etwas später nach dem Programmstart.
  • Schwache Referenz - Als das Programm gestartet wurde, begannen die Objekte zu finalisieren und wurden fast sofort gesammelt. Die meisten Gegenstände wurden in der Müllabfuhr der jungen Generation gesammelt.
  • Phantomreferenz - Ähnlich wie bei einer schwachen Referenz wurden auch Objekte mit Phantomreferenz sofort finalisiert und der Müll wurde sofort eingesammelt. Es gab keine GC der alten Generation und alle Objekte wurden in der Müllabfuhr der jungen Generation selbst gesammelt.

Ausführlichere Grafiken, Statistiken und Beobachtungen zu diesem Experiment finden Sie hier .

0
Ravi K

Man sollte sich bewusst sein, dass ein schwach referenziertes Objekt nur dann gesammelt 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.

0
Fai Lau

WeakReference : Objekte, die nur schwach referenziert werden, werden bei jedem GC-Zyklus (Moll oder Full) erfasst.

SoftReference : Wenn Objekte erfasst werden, die nur schwach referenziert werden, hängt Folgendes ab: 

  1. -XX: SoftRefLRUPolicyMSPerMB = N-Flag (Standardwert ist 1000, auch bekannt als 1 Sekunde) 

  2. Menge an freiem Speicher im Heap. 

    Beispiel: 

    • heap hat 10 MB freien Speicherplatz (nach vollständiger GC);
    • -XX: SoftRefLRUPolicyMSPerMB = 1000 

    Objekte, auf die nur von SoftReference verwiesen wird, werden erfasst, wenn das letzte Mal, als auf das Objekt zugegriffen wurde, länger als 10 Sekunden ist.

0
Artem Petrov