Kopieralgorithmus
Schauen wir uns zunächst den Kopieralgorithmus an. Der Kopieralgorithmus unterteilt den Speicher in zwei Intervalle. Zu jedem Zeitpunkt können alle dynamisch zugewiesenen Objekte nur in einem der Intervalle zugewiesen werden . (als aktives Intervall bezeichnet), während das andere Intervall (als Leerlaufintervall bezeichnet) inaktiv ist.
Wenn der effektive Speicherplatz erschöpft ist, pausiert die JVM das Programm und startet den GC-Thread des Kopieralgorithmus. Als nächstes kopiert der GC-Thread alle überlebenden Objekte im aktiven Intervall in das freie Intervall und ordnet sie streng nach der Speicheradresse an. Gleichzeitig aktualisiert der GC-Thread die Speicherreferenzadresse des überlebenden Objekts an die neue Speicheradresse.
Zu diesem Zeitpunkt wurde das freie Intervall durch das aktive Intervall ausgetauscht, und alle Müllobjekte verbleiben nun im ursprünglichen aktiven Intervall, dem aktuellen freien Intervall. Tatsächlich wurden die Müllobjekte alle auf einmal recycelt, wenn das aktive Intervall in ein Leerzeichenintervall umgewandelt wurde.
Klingt es kompliziert?
Tatsächlich ist es überhaupt nicht kompliziert, diesen Algorithmus auf der Grundlage des vorherigen Kapitels zu verstehen. LZ zeichnet für Sie ein Bild zur Veranschaulichung des Problems, wie unten gezeigt.
Tatsächlich ist dieses Bild immer noch das Beispiel aus dem vorherigen Kapitel, aber jetzt wird der Speicher durch den Kopieralgorithmus in zwei Teile geteilt. Schauen wir uns den GC an Wie die beiden Bereiche danach aussehen, wird unten gezeigt.
Sie können sehen, dass die Objekte 1 und 4 gelöscht wurden, während die Objekte 2, 3, 5 und 6 gerade im freien Intervall angeordnet sind den aktuellen Aktivitätsbereich. Zu diesem Zeitpunkt ist die linke Hälfte zu einem Leerlaufintervall geworden. Es ist nicht schwer, sich vorzustellen, dass die linke Hälfte nach dem nächsten GC wieder zu einem aktiven Intervall wird.
Offensichtlich gleicht der Kopieralgorithmus die Mängel des chaotischen Speicherlayouts im Mark/Clear-Algorithmus aus. Aber gleichzeitig sind auch seine Mängel offensichtlich.
1. Es verschwendet die Hälfte des Speichers, was schrecklich ist.
2. Wenn die Überlebensrate des Objekts sehr hoch ist, können wir unter der Annahme einer 100-prozentigen Überlebensrate alle Objekte kopieren und alle Referenzadressen zurücksetzen. Der Zeitaufwand für das Kopieren dieses Werks wird nicht mehr vernachlässigbar, wenn die Überlebensrate des Objekts ein bestimmtes Niveau erreicht.
Aus der obigen Beschreibung ist also nicht schwer zu erkennen, dass für die Verwendung des Replikationsalgorithmus zumindest die Überlebensrate des Objekts sehr niedrig sein muss und das Wichtigste ist, dass wir die Verschwendung von 50 überwinden müssen % des Speichers.
Markierungs-/Sortierungsalgorithmus
Der Markierungs-/Sortierungsalgorithmus ist dem Markierungs-/Löschalgorithmus sehr ähnlich. Er ist ebenfalls in zwei Phasen unterteilt: Markieren und Sortieren. Als nächstes stellt Ihnen LZ vor, was in diesen beiden Phasen getan wurde.
Markierung: Die erste Phase ist genau die gleiche wie der Markierungs-/Löschalgorithmus, der GC Roots durchläuft und dann die überlebenden Objekte markiert.
Organisation: Verschieben Sie alle überlebenden Objekte und ordnen Sie sie in der Reihenfolge ihrer Speicheradressen an. Anschließend wird der gesamte Speicher nach der Endspeicheradresse wiederverwendet. Daher wird die zweite Stufe als Endstufe bezeichnet.
Das Diagramm vor und nach dem GC ist dem Diagramm des Kopieralgorithmus sehr ähnlich, außer dass es keinen Unterschied zwischen dem aktiven Intervall und dem freien Intervall gibt und der Prozess dem Mark/Clear-Algorithmus sehr ähnlich ist im Zustand der Objekte im Speicher vor GC mit dem unten gezeigten Layout.
Dieses Bild ist eigentlich genau das gleiche wie der Mark/Clear-Algorithmus, mit der Ausnahme, dass LZ ein Rechteck zur Darstellung des Speichers hinzugefügt hat, um die kontinuierliche Anordnung der Speicherregeln zu erleichtern Bereich. Wenn der GC-Thread zu diesem Zeitpunkt mit der Arbeit beginnt, beginnt sofort die Markierungsphase. Diese Phase ist die gleiche wie die Markierungsphase des Markierungs-/Löschalgorithmus. Wir betrachten den Zustand des Objekts nach der Markierungsphase, wie unten gezeigt.
Es gibt nichts zu erklären, als nächstes sollte es die Organisationsphase sein. Schauen wir uns an, wie das Speicherlayout nach Abschluss der Sortierphase aussieht, wie unten gezeigt.
Wie Sie sehen können, werden die markierten überlebenden Objekte entsprechend der Speicheradresse organisiert und angeordnet, während der nicht markierte Speicher bereinigt wird. Wenn wir einem neuen Objekt Speicher zuweisen müssen, muss die JVM auf diese Weise nur die Startadresse des Speichers speichern, was offensichtlich viel weniger Aufwand verursacht als die Pflege einer freien Liste.
Es ist nicht schwer zu erkennen, dass der Markierungs-/Sortieralgorithmus nicht nur die Mängel des Speicherbereichs im Markierungs-/Löschalgorithmus ausgleichen kann, sondern auch die hohen Kosten der Halbierung des Speichers im Kopieralgorithmus eliminieren kann Man kann sagen, man schlägt zwei Fliegen mit einer Klappe, schlägt zwei Fliegen mit einer Klappe und schlägt zwei Fliegen mit einer Klappe. . . . Eine Frau und zwei Männer?
Jeder Algorithmus hat jedoch seine Nachteile. Der einzige Nachteil des Markierungs-/Organisationsalgorithmus besteht darin, dass er nicht nur alle überlebenden Objekte markieren, sondern auch die Referenzadressen aller überlebenden Objekte sortieren muss . In Bezug auf die Effizienz ist der Markierungs-/Sortierungsalgorithmus niedriger als der Kopieralgorithmus.
Algorithmuszusammenfassung
Hier fasst LZ die Gemeinsamkeiten der drei Algorithmen und ihre jeweiligen Vor- und Nachteile zusammen, damit Sie sie vergleichen können und es klarer wird.
Die wichtigsten Gemeinsamkeiten sind die folgenden zwei Punkte.
1. Die drei Algorithmen basieren alle auf dem Root-Suchalgorithmus, um zu bestimmen, ob ein Objekt recycelt werden soll. Die theoretische Grundlage, die den normalen Betrieb des Root-Suchalgorithmus unterstützt, ist der relevante Inhalt des Variablenbereichs in der Grammatik. Daher besteht die grundlegendste Möglichkeit, Speicherlecks zu verhindern, darin, den Variablenbereich zu beherrschen, anstatt die im vorherigen Kapitel zur Speicherverwaltung erwähnte Speicherverwaltungsmethode im C/C++-Stil zu verwenden.
2. Wenn der GC-Thread gestartet wird oder der GC-Prozess startet, müssen sie die Anwendung anhalten (die Welt stoppen).
LZ zeigt Ihnen die Unterschiede anhand der folgenden Punkte. (> Zeigt an, dass Ersteres besser ist als Letzteres, = bedeutet, dass beide den gleichen Effekt haben)
Effizienz: Kopieralgorithmus > Algorithmus markieren/organisieren > Die Effizienz hier ist nur ein einfacher Vergleich Aufgrund der zeitlichen Komplexität muss dies jedoch nicht unbedingt der Fall sein.
Speichergenauigkeit: Kopieralgorithmus = Markierungs-/Organisationsalgorithmus>
Speichernutzung: [b] Mark/Collate-Algorithmus = Mark/Sweep-Algorithmus > [/b]
Sie können sehen, dass der Mark/Clear-Algorithmus ein relativ rückständiger Algorithmus ist, aber die beiden letztgenannten Algorithmen basieren auf dieser Grundlage. Wie das Sprichwort sagt: „Vergiss den Brunnengräber nicht, wenn du drin bist.“ Probleme“, daher sollten Sie die Vorgänger des Mark/Sweep-Algorithmus nicht vergessen. Irgendwann kommt auch Mark/Sweep ins Spiel.
Fazit
Jetzt haben wir ein klares Verständnis der drei Algorithmen. Es ist ersichtlich, dass der Replikationsalgorithmus der Spitzenreiter ist, aber er verschwendet zu viel Speicher Berücksichtigen Sie die drei oben genannten Indikatoren. Der Markierungs-/Organisationsalgorithmus ist relativ reibungslos, aber die Effizienz ist immer noch unbefriedigend. Er verfügt über eine Markierungsstufe mehr als der Markierungs-/Löschalgorithmus Erinnerung.
Gibt es keinen optimalen Algorithmus?
Natürlich nicht. Die Welt ist fair und alles hat zwei Seiten. Wie könnte man jemanden finden, der schön, fleißig, reich, vernünftig ist, die richtige Persönlichkeit, den richtigen familiären Hintergrund, die richtige Größe und das richtige Aussehen hat? usw. Moment, eine passende Frau? Selbst wenn Sie einen finden, gibt es mindestens eine Sache, mit der diese Frau definitiv nicht zufrieden sein wird: Sie wird sich wahrscheinlich nicht zufällig in einen der fleißigen Affenfreunde verlieben, die LZ ähnlich sind. Möchten Sie sagen, dass Sie viel besser sind als LZ? Dann möchte LZ Ihnen nur sagen, dass Gao Fushuai nicht vor den Computer kriechen wird, um technische Artikel zu lesen, 0,0.
Aber die Alten sind großartig. Die Alten sagten, dass man bei der Suche nach einer Frau nicht die beste, sondern die passendste finden muss. Nachdem ich diesen Satz gehört hatte, hatte ich sofort das Gefühl, dass die Welt viel ist besser.
Der Algorithmus ist derselbe. Es gibt keinen besten Algorithmus, nur den am besten geeigneten Algorithmus.
Da diese drei Algorithmen ihre eigenen Mängel aufweisen, werden Experten dies natürlich nicht zulassen. Daher haben Experten vorgeschlagen, dass je nach den unterschiedlichen Eigenschaften des Objekts unterschiedliche Algorithmen verwendet werden können, ähnlich dem Prinzip, dass jede Karotte und jeder Kohl ihre eigenen Vorlieben hat. So geschah ein Wunder, und die Experten fanden schließlich den Algorithmus auf Gottesebene unter den GC-Algorithmen – den Generationssammlungsalgorithmus.
Wie dieser Algorithmus auf Gott-Ebene verarbeitet wird, wird LZ im nächsten Kapitel mit allen Affenfreunden besprechen. Ich hoffe, Sie können etwas gewinnen.
Das Obige ist der Inhalt der JVM-Speicherverwaltung ------ GC-Algorithmus (Kopieralgorithmus und Markierungs-/Sortierungsalgorithmus) Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php). .cn)!