Wenn ein Objekt im Speicher keine Referenz hat, bedeutet dies, dass das Objekt nicht mehr verwendet wird und es zu einem Kandidaten für die Müllsammlung werden kann. Da die Laufzeit des Müllsammlers ungewiss ist, ist die tatsächliche Recyclingzeit der Objekte, die Müll gesammelt werden können, ungewiss. Für ein Objekt, solange es eine Referenz gibt, wird es immer im Gedächtnis existieren. Wenn es immer mehr Objekte wie diese gibt, die den Gesamtspeicher im JVM überschreitet, wirft der JVM einen Fehler aus. Obwohl der spezifische Betrieb der Müllsammlung vom JVM kontrolliert wird, können Entwickler bis zu einem gewissen Grad mit dem Müllsammler interagieren, und es besteht der Zweck, dem Müllsammler besser zu helfen, den Speicher der Anwendung zu verwalten. Diese Interaktionsmethode besteht darin, das von JDK 1.2 eingeführte java.lang.ref -Paket zu verwenden.
1 starkes Zitat
Starke Zitate sind die häufigsten verwendeten Zitate. Wenn ein Objekt eine starke Referenz hat, wird der Müllsammler es niemals recyceln. Wenn der Speicherraum nicht ausreicht, würde die virtuelle Java -Maschine eher einen Fehler mit dem OutofMemoryError machen, um das Programm abnormal zu beenden, und Objekte nicht mit starken Verweisen recyceln, um das Problem des unzureichenden Speichers zu lösen.
Zum Beispiel ist Datum Datum = neues Datum (), Datum ist ein starker Verweis auf ein Objekt. Überall im Programm können starke Hinweise auf Objekte überall übergeben werden. In vielen Fällen verweisen mehrere Referenzen gleichzeitig auf dasselbe Objekt. Die Existenz starker Referenzen begrenzt die Überlebenszeit eines Objekts im Gedächtnis. Wenn Objekt A einen starken Hinweis auf Objekt B enthält, ist im Allgemeinen die Überlebenszeit von Objekt B nicht kürzer als Objekt A. Wenn das Objekt A nicht ausdrücklich die Referenz von Objekt B auf NULL feststellt, wird der Müll nicht mehr darauf hingewiesen, dass das Objekt A auf sie zeigt, und es ist möglich, die Möglichkeit zu erhalten, die Gelegenheit zu erfassen.
Beispielcode:
Paket com.skywang.java; öffentliche Klasse Strongreferencetest {public static void main (String [] args) {myDate Date = new myDate (); System.gc (); }} Auslaufergebnisse:
<Nein Ausgabe>
Das Ergebnis zeigt, dass die Müllsammlung, obwohl es ausdrücklich genannt wird, eine starke Referenz für das Datum ist und das Datum nicht recycelt wird.
Zusätzlich zu starken Referenzen bietet das Paket von Java.lang.REF für ein Objekt unterschiedliche Referenzmethoden. Der Müllsammler des JVM hat unterschiedliche Möglichkeiten, verschiedene Arten von Referenzen zu bearbeiten.
2 weiche Zitate
Wenn ein Objekt nur weiche Referenzen hat, ist der Speicherraum ausreichend und der Müllsammler recycelt ihn nicht. Wenn der Speicherraum nicht ausreicht, wird der Speicher dieser Objekte recycelt. Solange der Müllsammler ihn nicht recycelt, kann das Objekt vom Programm verwendet werden. Weiche Referenzen können verwendet werden, um speicherempfindliche Caches zu implementieren.
Eine weiche Referenz kann in Verbindung mit einer Referenzwarteschlange (Referenz) verwendet werden. Wenn das von der sanften Referenz verwiesene Objekt vom Garbage Collector recycelt wird, fügt die virtuelle Java -Maschine die weiche Referenz zur zugehörigen Referenzwarteschlange hinzu.
Weiche Referenzen sind schwächer als starke Referenzen in Stärke und werden durch Weiche dargestellt. Seine Funktion besteht darin, den Müllsammler mitzuteilen, welche Objekte im Programm weniger wichtig sind und vorübergehend recycelt werden können, wenn nicht genügend Speicher vorliegt. Wenn es in der JVM nicht genügend Speicher gibt, befreien der Müllsammler Objekte, auf die nur durch weiche Referenzen hingewiesen werden. Wenn alle diese Objekte freigegeben werden und der Speicher nicht ausreicht, wird ein Fehler mit einem OutofMemory -Fehler geworfen. Weiche Referenzen sind ideal zum Erstellen von Caches. Wenn das System nicht ausreicht, kann der Inhalt im Cache freigegeben werden. Betrachten Sie beispielsweise ein Image -Editor -Programm. Das Programm wird alle Inhalte der Bilddatei für eine einfache Verarbeitung in den Speicher eingeleitet. Benutzer können auch mehrere Dateien gleichzeitig öffnen. Wenn gleichzeitig zu viele Dateien geöffnet werden, kann dies zu einem unzureichenden Speicher führen. Wenn weiche Referenzen verwendet werden, um auf den Inhalt der Bilddatei zu verweisen, kann der Müllkollektor diesen Speicher bei Bedarf zurückfordern.
Beispielcode:
Paket com.skywang.java; import java.lang.ref.softreference; public class widtreferencetest {public static void main (String [] args) {SofTreference ref = new Softreferenz (neuer mydate ()); Referencetest.DrainMemory (); }} Auslaufergebnisse:
<Nein Ausgabe>
Ergebnisse: Wenn der Speicher nicht ausreicht, wird die weiche Referenz beendet. Wenn weiche Referenzen verboten sind,
SofTreference Ref = New Softrreference (neuer myDate ()); Referencetest.DrainMemory ();
Äquivalent zu
MyDate date = new myDate (); // Es liegt an der JVM, wenn (jvm.infiated memory ()) {Date = null; System.gc ();} 3 Schwache Zitate
Eine schwache Referenz ist schwächer als weiche Referenz in der Stärke und wird von der WeaCreference -Klasse ausgedrückt. Sein Ziel ist es, sich auf ein Objekt zu beziehen, aber es verhindert nicht, dass das Objekt recycelt wird. Wenn eine starke Referenz verwendet wird, kann das referenzierte Objekt nicht recycelt werden. Schwache Zitate haben dieses Problem nicht. Wenn der Müllsammler ausgeführt wird, wird das Objekt recycelt, wenn alle Verweise auf ein Objekt schwache Referenzen sind. Die Funktion schwacher Referenzen besteht darin, die Kopplungsbeziehung zwischen Objekten in der Überlebenszeit durch starke Referenzen zu lösen. Die häufigste Verwendung schwacher Referenzen ist in den Sammlungsklassen, insbesondere in Hash -Tabellen. Mit der Hash -Tabellenschnittstelle kann jedes Java -Objekt als Schlüssel verwendet werden. Wenn ein Schlüsselwertpaar in die Hash-Tabelle eingefügt wird, hat das Hash-Tabellenobjekt selbst einen Hinweis auf diese Schlüssel- und Wertobjekte. Wenn diese Referenz eine starke Referenz ist, werden die Schlüssel- und Wertobjekte, die darin enthalten sind, nicht recycelt, solange das Hash -Tabellenobjekt selbst lebt. Wenn eine Hash-Tabelle mit einer langen Überlebenszeit viele Schlüsselwertpaare enthält, kann sie schließlich den gesamten Speicher im JVM verbrauchen.
Die Lösung für diese Situation besteht darin, schwache Verweise zu verwenden, um diese Objekte zu verweisen, damit sowohl Schlüssel- als auch Wertobjekte in der Hash -Tabelle Müll gesammelt werden können. In Java wird WewasMap vorgelegt, um dieses gemeinsame Bedürfnis zu befriedigen.
Beispielcode:
Paket com.skywang.java; import Java.lang.Ref.WeakReference; öffentliche Klasse Weapreferencetest {public static void main (String [] args) {Wecreference ref = new Wecreference (new mydate ()); System.gc (); }} Auslaufergebnisse:
OBJ [Datum: 1372142034360] ist GC
Ergebnisse: Wenn die JVM -Müllsammlung ausgeführt wird, werden schwache Referenzen beendet.
WeaCreference Ref = New Wecreference (New MyDate ()); System.gc ();
Äquivalent zu:
MyDate date = new myDate (); // Garbage Collection if (jvm.Infuffed Memory ()) {Date = null; System.gc ();} Der Unterschied zwischen schwachen Referenzen und weichen Referenzen besteht darin, dass Objekte mit nur schwachen Referenzen einen kürzeren Lebenszyklus haben. Während des Vorgangs eines Müllkollektors, der den Speicherbereich unter seiner Gerichtsbarkeit scannt, wird sein Gedächtnis, sobald ein Objekt mit nur schwachen Referenzen gefunden wurde, recycelt, unabhängig davon, ob der aktuelle Speicherplatz ausreicht oder nicht. Da der Garbage Collector jedoch ein Faden mit sehr geringem Priorität ist, kann er nicht unbedingt sehr schnell für Objekte entdeckt werden, die nur schwache Referenzen haben.
Eine schwache Referenz kann in Verbindung mit einer Referenzwarteschlange (Referenz) verwendet werden. Wenn das von einer schwache Referenz verwiesene Objekt Müll erhoben wird, fügt die java -virtuelle Maschine die schwache Referenz auf die zugehörige Referenzwarteschlange hinzu.
4 Illusionszitate
Auch als Ghost -Zitate bezeichnet ~ Bevor wir Ghost Quotes einführen, müssen wir zunächst den von Java bereitgestellten Objektabschlussmechanismus einführen. In der Objektklasse gibt es eine Finalize -Methode. Die ursprüngliche Absicht seines Designs ist es, einige Reinigungsarbeiten auszuführen, bevor ein Objekt tatsächlich recycelt wird. Da Java keinen Mechanismus bietet, der C ++ Destructor ähnelt, wird er durch die Abschlussmethode implementiert. Das Problem ist jedoch, dass die Laufzeit des Müllsammlers nicht festgelegt ist, sodass die tatsächliche Laufzeit dieser Reinigungsarbeiten nicht vorhergesagt werden kann. Eine Phantomreferenz kann dieses Problem lösen. Wenn Sie eine Ghost -Referenz -Phantomreferenz erstellen, müssen Sie eine Referenzwarteschlange angeben. Wenn die Abschlussmethode eines Objekts aufgerufen wurde, wird die Geisterreferenz des Objekts zur Warteschlange hinzugefügt. Wenn Sie den Inhalt in der Warteschlange überprüfen, wissen Sie, ob ein Objekt recycelt werden kann.
Die Verwendung von Geisterreferenzen und ihrer Warteschlangen ist selten und wird hauptsächlich zur Implementierung einer relativ feinen Speicherverwendungsregelung verwendet, was für mobile Geräte sehr bedeutsam ist. Das Programm kann den Speicher anfordern, um ein neues Objekt zu erstellen, nachdem festgestellt wurde, dass ein Objekt recycelt werden soll. Auf diese Weise kann der vom Programm konsumierte Speicher relativ niedrig aufrechterhalten werden.
Beispielsweise gibt der folgende Code ein Beispiel für die Implementierung eines Puffers.
öffentliche Klasse Phantombuffer {private byte [] data = new byte [0]; private referencequeue <Byte []> queue = new Referencequeue <Byte []> (); private PhantomReference <Byte []> Ref = New PhantomReference <Byte []> (Daten, Warteschlange); public byte [] get (int size) {if (size <= 0) {neue illegalArgumentException ("Falsche Puffergröße"); } if (data.length <Größe) {data = null; System.gc (); // erzwingen Sie den Müllsammler aus, versuchen Sie {queue.remove (); // Diese Methode blockiert, bis die Warteschlange nicht leerer Ref.Clear () ist; // Die Geisterreferenz wird nicht automatisch gelöscht, Sie müssen Ref = Null ausführen. Daten = neues Byte [Größe]; Ref = New PhantomReference <Byte []> (Daten, Warteschlange); } catch (interruptedException e) {e.printstacktrace (); }} Daten zurückgeben; }} Im obigen Code wird jedes Mal, wenn ein neuer Puffer angewendet wird, zuerst sichergestellt, dass das Byte -Array des vorherigen Puffers erfolgreich recycelt wurde. Die Entfernenmethode, auf die sich auf die Warteschlange bezieht, blockiert die Warteschlange, bis eine neue Geisterreferenz hinzugefügt wird. Es ist jedoch zu beachten, dass dieser Ansatz dazu führt, dass der Müllsammler zu oft ausgeführt wird, was dazu führen kann, dass das Programm zu niedrig ist.
Beispielcode:
Paket com.skywang.java; import Java.lang.Ref.Referencequeue; Import Java.lang.Ref.PhantomReference; öffentliche Klasse Phantomreferencetest {public static void main (String [] args) {Referenzqueue = new Referencequeue (); PhantomReference Ref = New PhantomReference (New MyDate (), Warteschlange); System.gc (); }} Auslaufergebnisse:
OBJ [Datum: 1372142282558] ist GC
Das Ergebnis zeigt, dass die Illusionsreferenz nach der Instanziierung beendet wird.
Referenzqueue -Queue = new Referencequeue (); PhantomReference Ref = New PhantomReference (New MyDate (), Warteschlange); System.gc ();
Äquivalent zu:
MyDate Date = new myDate (); Datum = null;