Wenn es um Müllsammlung (GC) geht, werden viele Menschen sie natürlich mit Java in Verbindung bringen. In Java müssen sich Programmierer nicht um die dynamische Speicherzuweisung und die Müllsammlung kümmern. All dies bleibt dem JVM überlassen.
Wie der Name schon sagt, soll die Müllsammlung den von Müll besetzten Raum freisetzen. Welche Art von Objekten wird in Java als "Müll" betrachtet? Wenn einige Objekte als Müll festgelegt sind, welche Strategie sollte zum Recyceln (Platz frei) verwendet werden? Was sind die typischen Müllsammler in aktuellen kommerziellen virtuellen Maschinen? Lassen Sie uns diese Themen nacheinander diskutieren. Hier ist der Verzeichnisriss dieses Artikels:
Wie kann ich bestimmen, ob ein Objekt "Müll" ist?
Typischer Müllsammlungsalgorithmus Typischer Müllsammler
1. Wie kann ich bestimmen, ob ein Objekt "Müll" ist?
In diesem Abschnitt verstehen wir zunächst die grundlegendste Frage: Wenn wir feststellen, dass ein Objekt "Müll" ist? Wie bestimmt der Müllsammler, da die Aufgabe des Müllkollekters darin besteht, den vom Müllobjekt für die Verwendung von neuen Objekten besetzten Raum zu recyceln, dass ein Objekt "Müll" ist? Das heißt, wie man beurteilt, dass ein Objekt recycelt werden kann.
In Java ist es Objekten durch Referenzen zugeordnet, dh wenn Sie Objekte bedienen möchten, muss es durch Referenzen durchgeführt werden. Dann ist es offensichtlich, dass ein einfacher Weg zu beurteilen ist, ob ein Objekt durch Referenzzählung recycelt werden kann. Wenn ein Objekt keine Referenzen zugeordnet ist, bedeutet dies, dass das Objekt im Grunde genommen wahrscheinlich nicht an anderer Stelle verwendet wird, und dann wird das Objekt zu einem recycelbaren Objekt. Diese Methode wird zur Referenzzählmethode.
Diese Methode ist durch ihre einfache Implementierung und hohe Effizienz gekennzeichnet, kann jedoch nicht das Problem der kreisförmigen Referenzen lösen, sodass diese Methode nicht in Java angewendet wird (Python verwendet Referenzzählmethode). Schauen Sie sich den folgenden Code an:
public class main {public static void main (String [] args) {myObject Object1 = new myObject (); MyObject Object2 = new myObject (); Object1.Object = Object2; Object2.Object = Object1; Object1 = null; Object2 = null; }} Klasse myObject {public Object Object = null;}Die letzten beiden Sätze weisen NULL Object1 und Object2 zu, was bedeutet, dass die von Object1 und Object2 vermittelten Objekte nicht mehr zugänglich sind. Da sie sich jedoch aufeinander beziehen, beträgt ihre Referenzzahl nicht 0, dann wird der Müllsammler sie niemals recyceln.
Um dieses Problem zu lösen, wird in Java die Methode zur Zugangsanalyse übernommen. Die Grundidee dieser Methode besteht darin, eine Reihe von "GC -Roots" -Objekten als Ausgangspunkt zu durchsuchen. Wenn es keinen zugänglichen Pfad zwischen "GC -Wurzeln" und einem Objekt gibt, soll das Objekt nicht erreichbar sein. Es ist jedoch zu beachten, dass das als nicht erreichbare Objekt nicht unbedingt zu einem recycelbaren Objekt wird. Ein Objekt, das als unerreichbar beurteilt wird, muss mindestens zwei Markierungsprozesse durchlaufen, um ein recycelbares Objekt zu werden. Wenn es immer noch keine Möglichkeit gibt, während dieser beiden Markierungsprozesse ein recycelbares Objekt zu werden, wird es im Grunde genommen zu einem recycelbaren Objekt.
Wie die Methode zur Zugänglichkeitsanalyse betrieben wird, habe ich sie noch nicht sehr klar verstanden. Wenn ein Freund klarer ist, geben Sie mir bitte einen Rat.
Lassen Sie uns unten ein Beispiel sehen:
Objekt aObj = new Object (); Object bobj = new Object (); Object COBJ = New Object (); aObj = bobj; aObj = cobj; cobj = null; aObj = null;
Welche Zeile kann ein Objekt recycelbar machen? Der Code in Zeile 7 führt dazu, dass Objekte recycelbare Objekte werden. Warum es den Lesern überlassen bleibt, für sich selbst zu denken.
Schauen wir uns ein anderes Beispiel an:
String str = new String ("Hallo"); SofTreference <String> sr = new SofTreference <String> (new String ("java"); WeapReference <String> WR = New Wecreference <string> (new String ("World"));Welcher dieser drei Sätze wird ein String -Objekt recycelbar machen? Satz 2 und 3, und Satz 2 bestimmt das String -Objekt als recycelbares Objekt, wenn nicht genügend Speicher vorliegt, und im dritten Satz wird das String -Objekt in jedem Fall als recycelbares Objekt bestimmt.
Lassen Sie uns schließlich die gemeinsamen Situationen zusammenfassen, in denen Objekte als recycelbare Objekte beurteilt werden, die normalerweise auftreten:
1) Zeigen Sie den Wert einer Referenz auf NULL an oder zeigen Sie die Referenz, die bereits auf ein Objekt auf ein neues Objekt hingewiesen hat, z. B. den folgenden Code:
Objekt obj = new Object (); obj = null; Objekt obj1 = neues Objekt (); Objekt obj2 = neues Objekt (); obj1 = obj2;
2) Lokaler Hinweis auf das Objekt, auf das hingewiesen wurde, wie z. B. den folgenden Code:
void fun () {...... für (int i = 0; i <10; i ++) {Object obj = new Object (); System.out.println (obj.getClass ()); }}Jedes Mal, wenn die Schleife ausgeführt wird, wird das generierte Objektobjekt zu einem recycelbaren Objekt.
3) Nur schwache Referenzen sind mit Objekten verbunden, wie z. B.:
Weapreference <String> wr = new Wecreference <string> (neue String ("Welt"));2. Typischer Garbage Collection Algorithmus
Nachdem er festgestellt hat, welcher Müll recycelt werden kann, muss der Müllsammler die Müllsammlung beginnen, aber ein Problem ist: Wie man Müll effizient sammelt. Da die Spezifikation der Java Virtual Machine keine klaren Vorschriften für die Implementierung eines Müllsammlers enthält, können die virtuellen Maschinen jedes Herstellers einen Müllsammler auf unterschiedliche Weise implementieren, so
1.Mark-Sweep (Mark-Clear) -Algorithmus
Dies ist der grundlegendste Algorithmus zur Müllsammlung. Der Grund, warum es am grundlegendsten ist, ist, dass es am einfachsten ist, die einfachste und die einfachste Idee zu implementieren. Der markierte Algorithmus ist in zwei Phasen unterteilt: die Markierungsphase und die Clearing-Stufe. Die Aufgabe der Markierungsphase besteht darin, alle Objekte zu markieren, die recycelt werden müssen, und in der Klärung ist es, den von den markierten Objekten besetzten Raum zu recyceln. Der spezifische Prozess ist in der folgenden Abbildung dargestellt:
Aus der Abbildung ist leicht zu erkennen, dass der Markierungsalgorithmus einfacher zu implementieren ist, aber es gibt ein ernstes Problem, dass es einfach ist, Speicherfragmente zu erzeugen. Zu viele Fragmente können dazu führen, dass bei der Zuweisung von Platz für große Objekte im nachfolgenden Prozess nicht genügend Platz ist und eine neue Müllsammlung im Voraus ausgelöst wird.
2. Kopieren (Kopier-) Algorithmus
Um die Mängel des Mark-Sweep-Algorithmus zu lösen, wurde der Kopieralgorithmus vorgeschlagen. Es unterteilt den verfügbaren Speicher in zwei gleiche Größe nach Kapazität und verwendet jeweils nur ein Stück. Wenn dieses Stück Speicher aufgebraucht wird, kopieren Sie das immer noch lebende Objekt in ein anderes Stück und räumen Sie dann den gebrauchten Speicherraum sofort auf, sodass Probleme mit der Speicherfragmentierung nicht auftreten. Der spezifische Prozess ist in der folgenden Abbildung dargestellt:
Obwohl dieser Algorithmus einfach zu implementieren, effizient zu laufen und nicht einfach zu erzeugen ist, ist es teuer, den Speicherraum zu verwenden, da der Speicherspeicher auf die Hälfte des ursprünglichen reduziert wird.
Offensichtlich hat die Effizienz des Kopieralgorithmus viel mit der Anzahl der überlebenden Objekte zu tun. Wenn es viele überlebende Objekte gibt, wird die Effizienz des Kopieralgorithmus stark reduziert.
3.Mark-Compact (Mark-Kollation) -Algorithmus
Um die Mängel des Kopierungsalgorithmus zu lösen und den Speicherraum voll auszunutzen, wird der Mark-Compact-Algorithmus vorgeschlagen. Der Algorithmus markiert genauso wie Mark-Sweep, aber nach Abschluss der Marke werden die recycelbaren Objekte nicht direkt aufgeräumt, sondern alle lebenden Objekte zu einem Ende und räumt dann außerhalb der Endgrenze auf den Speicher auf. Der spezifische Prozess ist in der folgenden Abbildung dargestellt:
4. Generationensammlungsalgorithmus
Der Generationskollektionalgorithmus wird derzeit von den meisten JVM -Müllsammlern verwendet. Seine Kernidee besteht darin, das Gedächtnis gemäß dem Lebenszyklus des Überlebens des Objekts in verschiedene Regionen zu unterteilen. Im Allgemeinen ist das Haufenbereich in die alte Generation und die junge Generation unterteilt. Das Merkmal der alten Generation ist, dass nur eine kleine Anzahl von Objekten jedes Mal recycelt werden muss, wenn der Müll gesammelt wird, während das Merkmal der neuen Generation darin besteht, dass eine große Anzahl von Objekten jedes Mal recycelt werden muss, wenn der Müll gesammelt wird. Dann kann der am besten geeignete Sammelalgorithmus gemäß den Merkmalen verschiedener Generationen übernommen werden.
Gegenwärtig übernehmen die meisten Müllsammler den Kopieralgorithmus für die neue Generation, da in der neuen Generation die meisten Objekte jedes Mal recycelt werden müssen, wenn die Müllsammlung gesammelt wird, was bedeutet, dass die Anzahl der Operationen, die kopiert werden müssen, relativ gering ist, aber in Wirklichkeit ist der Raum der neuen Generation nicht gemäß einem Verhältnis von 1: 1 geteilt. Im Allgemeinen ist die neue Generation in einen größeren Edenraum und zwei kleinere Überlebenderäume unterteilt. Jedes Mal, wenn der Eden-Raum und einer der Überlebenden Räume verwendet werden, werden beim Recycling die noch überfluteten Objekte in Eden und Survivor in einen anderen Überlebendenraum kopiert, und dann werden die Eden und die gerade verwendeten Überlebenden gereinigt.
Da das Alter lautet, dass jedes Mal nur eine kleine Anzahl von Objekten recycelt wird, wird der Mark-Kompaktalgorithmus im Allgemeinen verwendet.
Beachten Sie, dass es außerhalb des Haufensbereichs eine weitere Generation gibt, die permanente Generation ist, mit der Klassenklassen, Konstanten, Methodenbeschreibungen usw. das Recycling der dauerhaften Generation hauptsächlich zwei Teile recycelt: verworfene Konstanten und nutzlose Klassen.
3. Typischer Müllsammler
Der Algorithmus zur Müllsammlung ist die theoretische Grundlage des Speicherrecyclings, und der Müllsammler ist die spezifische Implementierung des Speicherrecyclings. Das Folgende ist eine Beschreibung mehrerer Müllsammler, die vom Hotspot (JDK 7) Virtual Machine bereitgestellt werden. Benutzer können Sammler kombinieren, die in jeder Zeit nach ihren eigenen Bedürfnissen verwendet werden.
1.Serial/seriell alt
Der serielle/serielle alte Sammler ist der grundlegendste und älteste Sammler. Es ist ein einzelner Thread -Sammler und muss alle Benutzer -Threads innehalten, wenn es die Müllsammlung durchführt. Der serielle Kollektor ist ein Kollektor für die neue Generation unter Verwendung des Kopierungsalgorithmus, und der serielle alte Kollektor ist ein Sammler für die alte Generation unter Verwendung des Mark-Kompaktalgorithmus. Sein Vorteil ist, dass es einfach und effizient ist, aber sein Nachteil ist, dass es den Benutzern eine Pause verursacht.
2.PARNEW
Der Parnew Collector ist eine Multi-Thread-Version des Serienkollektors, die mehrere Fäden für die Müllsammlung verwendet.
3.. Parallele Spur
Der Parallel Scavenge Collector ist eine neue Generation von Multithread -Sammlern (parallele Sammler). Während des Recyclings muss nicht andere Benutzer -Threads innehalten. Es verwendet den Kopieralgorithmus. Dieser Sammler unterscheidet sich von den ersten beiden Sammlern. Es ist hauptsächlich, um einen kontrollierten Durchsatz zu erreichen.
4. Parallele alt
Parallel Old ist eine alte Version des Parallel-Scavenge-Sammlers (Parallel Collector) unter Verwendung von Multithreading- und Mark-Kompaktalgorithmen.
5.cms
Der CMS -Kollektor (Current Marke Sweep) ist ein Sammler, der darauf abzielt, die kürzeste Erholungspausezeit zu erhalten. Es ist ein gleichzeitiger Sammler, der den Mark-Sweep-Algorithmus verwendet.
6.g1
Der G1-Sammler ist die hochmodernste Leistung in der heutigen Entwicklung der Sammlertechnologie. Es ist ein Kollektor für serverseitige Anwendungen, die die Umgebungen mit Multi-CPU- und Multi-Core-Umgebungen vollständig nutzen können. Daher handelt es sich um einen parallelen und Parallelitätskollektor, der ein vorhersehbares Pause -Zeitmodell erstellen kann.
Hier sind einige Dinge über die Speicherzuweisung:
In einer allgemeinen Richtung wird die Speicherzuweisung von Objekten auf dem Haufen zugewiesen. Objekte werden hauptsächlich in der neuen Generation von Eden Space und aus dem Weltraum zugewiesen, und in seltenen Fällen werden sie im Alter direkt zugewiesen. Wenn der Raum der neuen Generation des Eden -Raums und aus dem Raum nicht ausreicht, wird ein GC eingeleitet. Wenn der GC durchgeführt wird, können der Eden -Raum und aus dem Raum das Objekt aufnehmen und im Eden -Raum und aus dem Raum platziert werden.
Während des GC -Prozesses werden die überlebenden Objekte im Eden -Raum und aus dem Raum in den Weltraum verschoben, und dann werden der Eden -Raum und aus dem Raum gereinigt. Wenn der Raum nicht ausreichen kann, um ein Objekt während der Reinigung zu speichern, verschiebt es das Objekt in das Alter. Nach GC werden Eden -Raum und Raum genutzt. Wenn Sie das nächste Mal gc, wird das überlebende Objekt aus dem Raum kopiert und die Schleife wiederholt. Wenn ein Objekt einmal im Survivor -Gebiet GC entgeht, wird das Alter seines Objekts um 1 erhöht. Wenn das Objekt 15 Jahre alt ist, wird es in das mittlere Alter des Alters übergehen.
Im Allgemeinen werden große Objekte direkt dem Alter zugewiesen. Die sogenannten großen Objekte beziehen sich auf Objekte, die eine große Menge an kontinuierlichem Speicherplatz erfordern. Der häufigste Typ großer Objekte sind große Arrays, wie z. B.:
byte [] data = new Byte [4*1024*1024]
Diese Art von Speicherplatz wird im Allgemeinen direkt in älteren Menschen zugewiesen.
Natürlich sind die Zuordnungsregeln nicht zu 100% festgelegt, was davon abhängt, welche Art von Müllsammlerkombination und die relevanten Parameter des JVM derzeit verwendet werden.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.