In diesem Tutorial geht es darum, die grundlegende Java -Müllsammlung zu verstehen und wie es funktioniert. Dies ist der zweite Teil der Garbage Collection Tutorial Series. Ich hoffe, Sie haben den ersten Teil gelesen: " Eine kurze Einführung in den Mechanismus für die Sammlung von Java ".
Die Java -Müllsammlung ist ein automatisierter Prozess, mit dem der von Programmen verwendete Laufzeitspeicher verwaltet wird. Durch diesen Automatisierungsprozess entfernt der JVM den Aufwand von Programmierern, Ressourcen im Programm zuzuweisen und freien Speicherressourcen zuzuweisen.
Starten Sie die Java -Müllsammlung
Als automatischer Prozess müssen Programmierer den im Code angezeigten Müllsammlungsprozess nicht starten. System.gc () und runtime.gc () werden verwendet, um die JVM aufzufordern, die Müllsammlung zu starten.
Obwohl dieser Anfragemechanismus den Programmierern die Möglichkeit bietet, den GC -Prozess zu starten, liegt das Startup in der Verantwortung des JVM. Die JVM kann diese Anfrage ablehnen, sodass es keine Garantie dafür gibt, dass alle diese Anrufe die Müllsammlung durchführen. Die Auswahl des Start -up -Timings wird vom JVM bestimmt und hängt davon ab, ob der Edenbereich im Heap -Speicher verfügbar ist. Das JVM lässt diese Wahl für die Implementierung der Java -Spezifikation, und die spezifischen Algorithmen, die von verschiedenen Implementierungen verwendet werden, sind unterschiedlich.
Unnötig zu erwähnen, dass der Müllsammlungsprozess nicht durchgesetzt werden kann. Ich habe gerade eine Szene gefunden, in der Calling System.gc () Sinn macht. Lassen Sie uns in diesem Artikel die extremen Situationen kennenlernen, die für das Aufrufen von System.gc () geeignet sind .
Java Müllsammlungsprozess
Die Müllsammlung ist ein Prozess, in dem nutzlose Speicherplatz zurückgefordert und zukünftige Instanzen zur Verfügung gestellt werden.
Eden Area: Wenn eine Instanz erstellt wird, wird sie zunächst im Eden -Bereich der jungen Generation des Heap -Speichers aufbewahrt.
Hinweis: Wenn Sie diese Wörter nicht verstehen können, schlage ich vor, dass Sie diese Einführung in die Müllsammlung lesen, die eine detaillierte Einführung in Speichermodelle, JVM -Architekturen und diese Begriffe bietet.
Survivor -Zonen (S0 und S1): Im Rahmen des GC -Zyklus der jungen Generation (MinorGC) wird das überlebende Objekt (noch verwiesen) von der Edenzone zu S0 der Überlebendenzone bewegt. In ähnlicher Weise scannt der Garbage Collector S0 und bewegt die überlebende Instanz in S1.
(Anmerkung des Übersetzers: Wechseln die überlebenden Menschen in Eden und S0 nicht zu S1? Warum wechseln sie zuerst zu S0 und dann von S0 bis S1?)
Eine Instanz des Todes (nicht mehr verwiesen) wird als Müllsammlung gekennzeichnet. Abhängig vom Müllsammler (es gibt vier häufig verwendete Müllsammler, die im nächsten Tutorial beschrieben werden), werden entweder die markierten Instanzen ständig aus dem Speicher entfernt, oder der Recyclingprozess wird in einem separaten Prozess abgeschlossen.
Ältere Generation: Die ältere Generation ist der zweite logische Bereich im Heap -Speicher. Wenn der Müllsammler den MinorGC -Zyklus ausführt, wird die überlebende Instanz im Bereich S1Survivor in das Alter gefördert, während die nicht recycelten Objekte als recycelt markiert werden.
Old GC (MajorGC): Im Vergleich zum Java -Müllsammlungsprozess ist Old GC die letzte Stufe des Instanzlebenszyklus. MajorGC scannt den Müllrecyclingprozess älterer Menschen. Wenn nicht mehr auf Instanzen verwiesen werden, werden sie als recycelt gekennzeichnet, sonst bleiben sie weiterhin im Alter.
Memory Shard: Sobald eine Instanz aus dem Heap -Speicher gelöscht wird, wird der Standort leer und kann für die Zuweisung zukünftiger Instanzen verwendet werden. Diese freien Räume zerfressen den gesamten Speicherbereich. Für eine schnelle Zuordnung von Instanzen ist eine Defragmentierung erforderlich. Basierend auf den verschiedenen Auswahlmöglichkeiten des Müllsammlers wird der recycelte Speicherbereich entweder ständig in einem separaten GC -Prozess aussortiert oder abgeschlossen.
Ende der Fälle in der Müllsammlung
Bevor der Java -Müllkollektor eine Instanz freigibt und den Speicherplatz zurückerobert, nennt er die jeweilige Finalize () -Methode der Instanz, sodass die Instanz die Möglichkeit hat, die von ihm enthaltenen Ressourcen freizugeben. Obwohl es garantiert ist, dass Finalize () vor dem Rückgewinnungsspeicher aufgerufen wird, gibt es keine bestimmte Reihenfolge und Zeit. Die Reihenfolge zwischen mehreren Fällen ist unvorhersehbar und kann sogar parallel auftreten. Die Programme sollten die Reihenfolge zwischen Instanzen und Ressourcen mithilfe der Methode Finalize () nicht einstellen.
Alle Ausnahmen, die nicht im Abschlussvorgang gefangen sind, werden automatisch ignoriert, und der Abschlussprozess der Instanz wird abgesagt.
In der JVM -Spezifikation wird weder den Müllansammlungsmechanismus für schwache Referenzen diskutiert, noch hat sie klare Anforderungen. Die spezifische Implementierung wird von der Umsetzungspartei bestimmt.
Die Müllsammlung erfolgt von einem Daemon -Faden.
Wann erfüllt das Objekt die Bedingungen für die Müllsammlung?
Alle Instanzen haben keinen aktiven Thread -Zugriff.
Eine kreisförmige Referenzinstanz, auf die von keiner anderen Instanz zugegriffen wird.
Es gibt verschiedene Referenztypen in Java. Die Bestimmung, ob eine Instanz auf die Müllerhebungsbedingungen entspricht, hängt von ihrem Referenztyp ab.
| Referenztyp | Müllsammlung |
|---|---|
| Starke Referenz | Nicht entspricht der Müllsammlung |
| Weiche Referenz | Die Müllsammlung kann durchgeführt werden, wird aber ein letzter Ausweg sein |
| Schwache Referenz | Müllsammlung einhalten |
| Phantomreferenz | Müllsammlung einhalten |
Als Optimierungstechnik während des Kompilierungsprozesses kann der Java -Compiler den Instanzen Nullwerte zuweisen und damit die Instanz als recycelbar markieren.
Klasse Animal {public static void main (String [] args) {Animal Lion = New Animal (); System.out.println ("Main ist abgeschlossen."); } protected void enddefination () {System.out.println ("Ruhe in Frieden!"); }}In der obigen Klasse wurde das Löwenobjekt nach der Instanziation der Linie nie verwendet. Als Optimierungsmaß kann der Java -Compiler daher Lion = NULL nach dem Instantieren der Zeile direkt zuweisen. Daher kann die Finalize -Funktion "restInpeace!" Ausdrucken ausdrucken. Noch vor der SOP -Ausgabe. Wir können nicht beweisen, dass dies geschehen wird, da es davon abhängt, wie die JVM implementiert wird und welcher Speicher von der Laufzeit verwendet wird. Wir können jedoch noch einen lernen: Wenn der Compiler sieht, dass auf die Instanz in Zukunft niemals verwiesen wird, kann er den Instanzraum frühzeitig auswählen und frei machen.
Es gibt ein besseres Beispiel dafür, wenn Objekte der Müllsammlung entsprechen. Alle Attribute der Instanz können in Registern gespeichert werden, auf die dann zugegriffen und gelesen werden. Ausnahmslos werden diese Werte in die Instanz zurückgeschrieben. Obwohl diese Werte in Zukunft verwendet werden können, kann diese Instanz dennoch als Einhaltung der Müllsammlung gekennzeichnet werden. Dies ist ein sehr klassisches Beispiel, nicht wahr?
Dies ist ein sehr einfaches Beispiel, das der Müllsammlung entspricht, wenn sie NULL zugeordnet ist. Natürlich können komplexe Situationen wie die oben genannten Punkte sein. Dies ist eine Wahl des JVM -Implementierers. Ziel ist es, den kleinsten Speicherpflichtzdruck wie möglich zu hinterlassen, die Reaktionsgeschwindigkeit zu beschleunigen und den Durchsatz zu verbessern. Um dies zu erreichen, können JVM -Implementierer eine bessere Lösung oder einen besseren Algorithmus auswählen, um den Speicherplatz während des Müllsammlungsprozesses zurückzugewinnen.
Wenn die Methode Finalize () aufgerufen wird, veröffentlicht die JVM alle Synchronisationssperrungen auf dem Thread.
GCSCOPE -Beispielprogramm
Klasse gcScope {gcscope t; static int i = 1; public static void main (String args []) {gcscope t1 = new gcscope (); gcscope t2 = new gcscope (); gcscope t3 = new gcscope (); // kein Objekt ist für GCTIBLE. Das Objekt kann für gct3.t = t1; // kein Objekt für gct1 = null; // kein Objekt für gc berechtigt (t3.t immer noch einen Hinweis auf t1) t2 = null; // Kein Objekt ist für gc (t3.tt still einen Bezug auf t3). Die Objekte verweisen sich in einer rundeten Mode, die die Insel der Objekte ohne externe // Referenz bildet. Gcscope (); gcscope t2 = new gcscope (); gcscope t3 = new gcscope (); // Kein Objekt entspricht GCT1.t = T2; // Kein Objekt entspricht GCT2.T = T3; // NO -Objekt passt. t1) t2 = null; // kein Objekt entspricht GC (t3.tt hat immer noch einen Hinweis auf T2) t3 = null; // Alle drei Objekte entsprechen GC (keine von ihnen hat eine Referenz. // Nur die variable t der einzelnen Objekte weist aufeinander hin. aus Objekt "+i); i ++;}GC OutofMemoryError -Beispielprogramm
GC garantiert nicht die Sicherheit von Speicherüberlaufproblemen, und unachtsamer Code führt zur Ausgabe vonMemoryError.
Java.util.LinkedList importieren; Java.util.List; public class gc {public static void main (String [] main) {list l = new LinkedList (); // Geben Sie die Infinite -Schleife ein, die eine String zu der Liste hinzufügen: l auf jedem // iteration.do {L.Add ("New String (" Helly ");Ausgabe:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.LinkedList.linkLast(LinkedList.java:142) at java.util.LinkedList.add(LinkedList.java:338) at com.javapapers.java.GCScope.main(GCScope.java:12)
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels über kurz über den Implementierungsprozess der Java -Müllsammlung. Ich hoffe, es wird für alle hilfreich sein. Interessierte Freunde können weiterhin auf andere verwandte Themen auf dieser Website verweisen. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!