915 Stimmen

Was ist der Unterschied zwischen SoftReference und WeakReference in Java?

Was ist der Unterschied zwischen java.lang.ref.WeakReference y java.lang.ref.SoftReference ?

1036voto

Michael Myers Punkte 183216

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 aktuelle Widget 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), dass weakWidget.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 als WeakReferences 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.

230voto

driekken Punkte 11053

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.

216voto

Premraj Punkte 65511

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.

Quelle

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.

83voto

Thalaivar Punkte 22174

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 .

58voto

Samir Mangroliya Punkte 39089

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

Der Garbage Collector verwendet Algorithmen, um zu entscheiden, ob er ein leicht erreichbares Objekt nicht zurückfordert, sondern immer ein schwach erreichbares Objekt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X