Ich habe diesen Artikel über das Thema gelesen , verstehe ihn aber nicht wirklich. Bitte geben Sie mir einige Ratschläge zusammen mit Beispielen bei der Beschreibung der Konzepte.
Ich habe diesen Artikel über das Thema gelesen , verstehe ihn aber nicht wirklich. Bitte geben Sie mir einige Ratschläge zusammen mit Beispielen bei der Beschreibung der Konzepte.
Antworten:
Java bietet zwei verschiedene Arten / Klassen von Referenzobjekten : starke und schwache . Schwache Referenzobjekte können weiter in weich und Phantom unterteilt werden .
Gehen wir Punkt für Punkt.
Starkes Referenzobjekt
StringBuilder builder = new StringBuilder();
Dies ist der Standardtyp / die Standardklasse des Referenzobjekts, sofern nicht anders angegeben: Es builder
handelt sich um ein starkes Referenzobjekt. Diese Art von Referenz macht das referenzierte Objekt nicht für GC geeignet. Das heißt, wenn ein Objekt von einer Kette starker Referenzobjekte referenziert wird , kann kein Müll gesammelt werden.
Schwaches Referenzobjekt
WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);
Schwache Referenzobjekte sind nicht der Standardtyp / die Standardklasse des Referenzobjekts und sollten zur Verwendung explizit wie im obigen Beispiel angegeben werden. Diese Art von Referenz macht das Referenzobjekt für GC geeignet. Das heißt, wenn die einzige Referenz, die für das StringBuilder
Objekt im Speicher erreichbar ist, tatsächlich die schwache Referenz ist, kann der GC das StringBuilder
Objekt mit Müll sammeln . Wenn ein Objekt im Speicher nur über schwache Referenzobjekte erreichbar ist, ist es automatisch für die GC geeignet.
Schwachstellen
Es können zwei verschiedene Schwächungsstufen angegeben werden: weich und phantomisch .
Ein weiches Referenzobjekt ist im Grunde ein schwaches Referenzobjekt, das etwas mehr im Speicher verbleibt: Normalerweise widersteht es dem GC-Zyklus, bis kein Speicher mehr verfügbar ist und das Risiko besteht OutOfMemoryError
(in diesem Fall kann es entfernt werden).
Andererseits ist ein Phantomreferenzobjekt nur nützlich, um genau zu wissen, wann ein Objekt effektiv aus dem Speicher entfernt wurde: Normalerweise werden sie verwendet, um das seltsame Wiederbelebungs- / Auferstehungsverhalten von finalize () zu korrigieren , da sie das Objekt selbst nicht zurückgeben, sondern helfen nur dabei , ihre Gedächtnispräsenz im Auge zu behalten .
Schwache Referenzobjekte sind ideal zum Implementieren von Cache-Modulen. Tatsächlich kann eine Art automatische Räumung implementiert werden, indem der GC Speicherbereiche bereinigen kann, wenn Objekte / Werte durch eine starke Referenzkette nicht mehr erreichbar sind. Ein Beispiel ist die WeakHashMap , bei der schwache Schlüssel beibehalten werden.
Schwache Referenz:
Eine schwache Referenz ist einfach ausgedrückt eine Referenz, die nicht stark genug ist, um ein Objekt 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.
Soft Reference:
Eine weiche Referenz ist genau wie eine schwache Referenz, nur dass sie weniger darauf aus ist, das Objekt, auf das sie sich bezieht, wegzuwerfen. Ein Objekt, das nur schwach erreichbar ist (die stärksten Verweise darauf sind WeakReferences), wird beim nächsten Speicherbereinigungszyklus verworfen, aber ein Objekt, das nur schwach erreichbar ist, bleibt im Allgemeinen eine Weile bestehen.
Phantomreferenz:
Eine Phantomreferenz unterscheidet sich erheblich von SoftReference oder WeakReference. Der Griff um das Objekt ist so schwach, dass Sie das Objekt nicht einmal abrufen können - die Methode get () gibt immer null zurück. Die einzige Verwendung für eine solche Referenz besteht darin, zu verfolgen, wann sie in eine ReferenceQueue eingereiht wird, da Sie an diesem Punkt wissen, dass das Objekt, auf das sie zeigt, tot ist.
Dieser Text wurde extrahiert aus: https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
Der einfache Unterschied zwischen SoftReference
und WeakReference
wird von Android Developer bereitgestellt .
Der Unterschied zwischen a SoftReference
und a WeakReference
ist der Zeitpunkt, zu dem die Entscheidung getroffen wird, die Referenz zu löschen und in die Warteschlange zu stellen:
A SoftReference
sollte so spät wie möglich gelöscht und in die Warteschlange gestellt werden, dh wenn die Gefahr besteht, dass der VM der Speicher ausgeht.
A WeakReference
kann gelöscht und in die Warteschlange gestellt werden, sobald bekannt ist, dass es schwach referenziert ist.
Die drei Begriffe, die Sie verwendet haben, hängen hauptsächlich mit der Berechtigung von Object zusammen, Müll zu sammeln.
Schwache Referenz :: Diese Referenz ist nicht stark genug, um das Objekt zu zwingen, im Speicher zu bleiben. Es ist die Laune des Garbage Collectors , dieses Objekt für die Garbage Collection zu sammeln. Sie können diesen GC nicht zwingen, ihn nicht zu sammeln .
Soft Reference :: Es ist mehr oder weniger dasselbe wie die schwache Referenz. Man kann aber sagen, dass es das Objekt etwas stärker hält als die schwache Referenz aus der Garbage Collection.
Wenn die Garbage Collectors die schwache Referenz im ersten Lebenszyklus selbst erfassen, erfassen sie die Soft Reference im nächsten Zyklus der Garbage Collection.
Starke Referenz :: Es ist genau entgegengesetzt zu den beiden oben genannten Arten von Referenzen. Sie sind weniger geneigt, Müll zu sammeln (meistens werden sie nie gesammelt.)
Weitere Informationen finden Sie unter folgendem Link:
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html
Dieser Artikel kann sehr hilfreich sein, um starke, weiche, schwache und Phantomreferenzen zu verstehen.
Um Ihnen eine Zusammenfassung zu geben,
Wenn Sie einen starken Verweis auf ein Objekt haben, kann das Objekt niemals von GC (Garbage Collector) gesammelt / zurückgefordert werden.
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.
Wir schaffen Phantom Referenzen auf ein Objekt zu verfolgen , wenn das Objekt in die Warteschlange gestellt wird ReferenceQueue
. Sobald Sie wissen, dass Sie eine feinkörnige Finalisierung durchführen können. (Dies würde Sie davor bewahren, das Objekt versehentlich wiederzubeleben, da die Phantomreferenz Ihnen den Referranten nicht gibt.) Ich würde vorschlagen, dass Sie diesen Artikel lesen , um detaillierte Informationen darüber zu erhalten.
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 keinem GC-Zyklus entkommen 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 zu weicher 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.
4 Referenzgrade - Strong, Weak, Soft, Phantom
Stark - ist eine Art Referenz, die das referenzierte Objekt für die GC nicht geeignet macht. Builder-Klassen. zB - StringBuilder
Schwach - ist eine Referenz, die für GC in Frage kommt.
Soft - ist eine Art Referenz, deren Objekt für die GC in Frage kommt, bis Speicher verfügbar ist. Am besten für den Bildcache. Es wird sie halten, bis der Speicher verfügbar ist.
Phantom - ist eine Art Referenz, deren Objekt direkt für die GC in Frage kommt. Wird nur verwendet, um zu wissen, wann ein Objekt aus dem Speicher entfernt wird.
Verwendet:
Hier können Sie feststellen, wann ein Objekt genau aus dem Speicher entfernt wurde.
Wenn die
finalize()
Methode überladen ist, wird die GC für GC-berechtigte Objekte der beiden Klassen möglicherweise nicht rechtzeitig ausgeführt. Die Phantomreferenz macht sie also zuvor für GC geeignet.finalize()
Deshalb können Sie OutOfMemoryErrors auch dann erhalten, wenn der größte Teil des Heaps Müll ist.
Schwache Referenzen sind ideal, um die Cache-Module zu implementieren.
Dies sind Ihre regulären Objektreferenzen, die wir täglich codieren:
Employee emp = new Employee();
Die Variable "emp" enthält einen starken Verweis auf ein Employee-Objekt, und Objekte, die über eine Kette starker Verweise erreichbar sind, können nicht mit Speicherbereinigung belegt werden. Normalerweise ist dies das, was Sie wollen, aber nicht immer. Nehmen wir nun an, wir holen viele Mitarbeiter aus der Datenbank in einer Sammlung oder Karte ab und müssen sie regelmäßig verarbeiten. Um die Leistung zu erhalten, behalten wir sie im Cache.
Soweit dies gut ist, benötigen wir jetzt unterschiedliche Daten und diese Employee-Objekte, auf die nur im Cache verwiesen wird. Was verursacht einen Speicherverlust, weil diese Objekte nicht verwendet werden, aber immer noch nicht für die Speicherbereinigung geeignet sind und wir diese Objekte nicht aus dem Cache entfernen können, weil wir keinen Verweis auf sie haben? Hier müssen wir entweder den gesamten Cache manuell leeren, was mühsam ist, oder wir könnten andere Arten von Referenzen verwenden, z. B. schwache Referenzen.
Eine schwache Referenz fixiert ein Objekt nicht im Speicher und wird im nächsten GC-Zyklus einer GC unterzogen, wenn nicht auf andere Referenzen verwiesen wird. Wir können die von Java bereitgestellte WeakReference-Klasse verwenden, um die oben genannten Caches zu erstellen, in denen keine Objekte gespeichert werden, auf die nicht von einem anderen Ort verwiesen wird.
WeakReference<Cache> cache = new WeakReference<Cache>(data);
Um auf Daten zuzugreifen, müssen Sie cache.get () aufrufen. Dieser Aufruf zum Abrufen kann null zurückgeben, wenn die schwache Referenz Garbage Collected war: Sie müssen den zurückgegebenen Wert überprüfen, um NPEs zu vermeiden. Java bietet Sammlungen, die schwache Referenzen verwenden, z. B. speichert die WeakHashMap-Klasse Schlüssel (keine Werte) als schwache Referenzen. Wenn der Schlüssel GC'd ist, wird der Wert automatisch auch von der Karte entfernt.
Da schwache Referenzen auch Objekte sind, müssen wir sie bereinigen (sie sind nicht mehr nützlich, wenn das Objekt, auf das sie verweisen, GC-fähig war). Wenn Sie eine ReferenceQueue für eine schwache Referenz an den Konstruktor übergeben, hängt der Garbage Collector diese schwache Referenz an die ReferenceQueue an, bevor sie finalisiert oder GC-geprüft wird. Sie können diese Warteschlange regelmäßig verarbeiten und mit toten Referenzen umgehen.
Eine SoftReference ähnelt einer WeakReference, es ist jedoch weniger wahrscheinlich, dass Müll gesammelt wird. Weiche Referenzen werden nach Ermessen des Garbage Collectors als Reaktion auf den Speicherbedarf gelöscht. Die virtuelle Maschine garantiert, dass alle weichen Verweise auf leicht erreichbare Objekte gelöscht wurden, bevor jemals ein OutOfMemoryError ausgelöst wurde.
Phantomreferenzen sind die schwächsten aller Referenztypen. Wenn Sie get on aufrufen, wird immer null zurückgegeben. Ein Objekt wird nach seiner Fertigstellung phantomisch referenziert, aber bevor sein zugewiesener Speicher zurückgefordert wurde. Im Gegensatz zu schwachen Referenzen, die vor ihrer Fertigstellung in die Warteschlange gestellt werden oder GC-Phantomreferenzen werden selten verwendet.
Wie sind sie also nützlich? Wenn Sie eine Phantomreferenz erstellen, müssen Sie immer eine ReferenceQueue übergeben. Dies zeigt an, dass Sie eine Phantomreferenz verwenden können, um zu sehen, wann Ihr Objekt GC-fähig ist.
Hey, wenn schwache Referenzen in die Warteschlange gestellt werden, wenn sie als finalisiert, aber noch nicht GC-geprüft gelten, können wir eine neue starke Referenz auf das Objekt im Finalizer-Block erstellen und verhindern, dass das Objekt GC-geprüft wird. Ja, Sie können, aber Sie sollten das wahrscheinlich nicht tun. Um dies zu überprüfen, wird der GC-Zyklus für jedes Objekt mindestens zweimal durchgeführt, es sei denn, dieses Objekt ist nur über eine Phantomreferenz erreichbar. Aus diesem Grund kann Ihnen der Heap ausgehen, selbst wenn Ihr Speicher viel Müll enthält. Phantomreferenzen können dies verhindern.
Sie können mehr über meinen Artikel Arten von Referenzen in Java lesen (Stark, Weich, Schwach, Phantom) .