Heim  >  Artikel  >  Java  >  Java – detaillierte Erklärung des Garbage-Collection-Mechanismus

Java – detaillierte Erklärung des Garbage-Collection-Mechanismus

巴扎黑
巴扎黑Original
2017-07-18 18:15:431536Durchsuche

Ein Überblick

1. Müll

Die JVM-Garbage Collection zielt hauptsächlich auf den Heap-Müll ab der Stapel, da beim Starten des Threads Speicherplatz im Stapel zugewiesen wird und der Speicherplatz beim Beenden des Threads automatisch freigegeben wird und keine Echtzeitüberwachung erforderlich ist. Im Methodenbereich werden hauptsächlich Klasseninformationen sowie statische Variablen und Konstanten gespeichert sind in der Regel während der gesamten Programmlaufzeit gültig und es besteht keine Notwendigkeit für recycelte Objekte.

Müll bezieht sich auf Objekte, auf die Threads nicht zugreifen können. Ein Objekt kann nur verwendet werden, wenn es für den Thread sichtbar ist und vom Thread auch einfach verstanden werden kann als Objekt ohne jegliche Referenzen. Streng genommen schränkt der Ausdruck ohne Verweis auf ein Objekt den Umfang des Mülls ein. In einem Zirkelverweis verweist beispielsweise ein Objekt A auf ein anderes Objekt B und Objekt B auf A und die Verweise von A und B. Die Beziehung Wenn kein externes Objekt auf A oder B verweist, können A und B nicht in die Ausführung des Programms einbezogen werden, d. h. kein Thread kann auf sie zugreifen und sie werden zu nutzlosen Objekten Definition von Müll Motivation: Objekte, die nicht mehr verwendet werden, sind Müll, und A und B gehören natürlich zum Müll.

Manchmal wird Müll auch als nutzlose Objekte bezeichnet, und Nicht-Müll wird als lebende Objekte bezeichnet.

2. Speicherverlust

Das Phänomen, dass nutzlose Objekte weiterhin Speicher belegen und Speicherverschwendung verursachen, wird als Speicherverlust bezeichnet. Die Hauptursache für Speicherlecks besteht darin, dass langlebige Objekte nach der Verwendung immer noch Verweise auf kurzlebige Objekte enthalten, wie zum Beispiel den folgenden Code:

Ein Objekt wird in der Methode erstellt. Der Zweck der Objekterstellung besteht nur darin, auf die Methode doSome im Objekt zuzugreifen. Zu diesem Zeitpunkt wird nicht mehr auf das Objekt zugegriffen Die Referenzvariable obj zeigt immer noch auf das Objekt. Wenn eine Referenz vorhanden ist, wird das Objekt nicht als Müll betrachtet, aber das Objekt ist zu einem nutzlosen Objekt geworden und sollte dereferenziert werden, damit der Müllsammler den belegten Speicherplatz zurückgewinnen kann durch das Objekt. „obj=null;“

3. Speicherrecycling

Der Garbage Collector recycelt keine Objekte, sondern den von nutzlosen Objekten belegten Speicherplatz, sodass der Platz frei werden kann recycelt Wiederverwendbar.

4. Speicherfragmentierung

Der kleine, diskontinuierliche freie Speicherplatz, der während des Speicherzuweisungs- und Recyclingprozesses erzeugt wird, wie in der Abbildung dargestellt:

Da der zu recycelnde Raum verstreut ist, wird der verfügbare Raum nach Abschluss des Recyclings in einen aufgeteilt Da diese Einheiten klein sind und keine großen Datenmengen speichern können, muss zusätzlicher Speicherplatz für große Datenmengen geöffnet werden, was zu einer Speicherverschwendung führt.

Zwei Algorithmen zur Müllbestimmung

1. Referenzzählalgorithmus

angegeben, wenn das Objekt Wird erstellt Das Objekt fügt einen Referenzzähler hinzu. Immer wenn eine Variable auf das Objekt verweist, wird der Zähler um 1 erhöht. Wenn die Variable die Referenz freigibt, wird der Zähler um 1 dekrementiert. Wenn der Zähler zu irgendeinem Zeitpunkt 0 ist, bedeutet dies, dass Kein Objekt verweist auf das Objekt und das Objekt wird zu Müll.

Der inhärente Fehler des Referenzzählalgorithmus besteht darin, dass er das Problem der Zirkelverweise nicht lösen kann, d. h. selbst wenn die beiden Objekte im Zirkelverweis nicht mehr verwendet werden, werden sie verwendet gelten weiterhin als nutzbare Gegenstände und werden nicht vom Müllverwerter recycelt. Der JVM-Garbage-Collection-Mechanismus verwendet diesen Algorithmus nicht, sondern den folgenden Algorithmus zur Erreichbarkeitsanalyse.

2. Erreichbarkeitsanalysealgorithmus

Der Erreichbarkeitsanalysealgorithmus verwendet Tracking, um festzustellen, ob das Objekt lebendig ist Erreichte Objekte sind alle lebendige Objekte, und Objekte, die nicht auffindbar oder nicht erreichbar sind, sind nutzlose Objekte. Der Ausgangspunkt der Verfolgung ist jedes Objekt, auf das gerade zugegriffen wird. Suchen Sie ausgehend von diesem Objekt das Objekt, auf das das Objekt verweist, und bilden Sie eine Schleife, um eine Referenzkette zu bilden werden vom Thread verwendet und sind Müll. Wie in der Abbildung unten gezeigt, wird auf der linken Seite eine Referenzkette gebildet. Alle Objekte auf der Kette sind lebendige Objekte. Obwohl die Objekte auf der rechten Seite Referenzbeziehungen zueinander haben, befinden sie sich außerhalb der Referenzkette des Threads Sie sind also nutzlose Objekte.

Diese Analyse ist dynamisch, nicht statisch und ändert sich, wenn sich die Objektreferenzbeziehung ändert.

Drei Objektspeicherbereiche

Verschiedene Objekte haben unterschiedliche Lebenszyklen. Um den Speicher rechtzeitig zu recyceln, wird häufig eine Speicherbereinigung durchgeführt Bei Objekten mit kurzen Lebenszyklen ist die Anzahl der Garbage Collection-Scans relativ stabil und die Anzahl der Garbage Collections ist gering. Objekte mit unterschiedlichen Lebenszyklen werden in verschiedenen Bereichen des Speichers gespeichert, um unterschiedliche Garbage-Collection-Methoden zu verwenden.

JVM unterteilt den Objektspeicherraum in drei Bereiche: neue Generation, alte Generation und permanente Generation.

Die neue Generation

Die neue Generation wird gegründet, um Objekte mit kurzen Lebenszyklen schnell zu recyceln in der neuen Generation. Die neue Generation ist in drei Teile unterteilt: Eden, von Survivor, und To Survivor, mit einem Raumverhältnis von 8:1:1.

Neu erstellte Objekte werden zuerst in Eden platziert und mehrere GC (Garbage Collection) werden durchgeführt, nachdem der Eden-Bereich voll ist sind noch am Leben. Werden in den Von-Überlebensbereich übertragen. Wenn der Von-Überlebensbereich voll ist, werden die überlebenden Objekte in den Nach-Überlebensbereich übertragen. Wenn der Nach-Überlebensbereich voll ist, werden die überlebenden Objekte in die alte Generation übertragen.

JVM führt häufig GC für Objekte der jungen Generation durch. Die meisten Objekte werden in der jungen Generation recycelt, und eine kleine Anzahl wird in die alte Generation übernommen.

2. Alte Generation

Objekte der alten Generation sind Objekte, die mehrere GCs überstanden haben und einen längeren Lebenszyklus haben Es werden weniger GC-Operationen durchgeführt.

3. Permanente Generierung

Die permanente Generierung ist der Methodenbereich. Er speichert Klasseninformationen, statische Variablen und Konstanten Anwendung und wird im Allgemeinen nicht vom Garbage Collector verarbeitet.

Vier Garbage-Collection-Algorithmen

Der Garbage-Collection-Algorithmus ist der Algorithmus, der für die tatsächliche Sammlung nach der Garbage-Bestätigung verwendet wird. Es gibt drei gängige Algorithmen:

1. Mark-clear-Methode

Markieren Sie zunächst nutzlose Objekte und beanspruchen Sie dann den von den Objekten belegten Speicherplatz, der zum Speicher führt Fragmentierung und wird grundsätzlich nicht vom Algorithmus verwendet.

2. Kopieralgorithmus

Während der Garbage Collection werden alle überlebenden Objekte in einem anderen Bereich kopiert Löschen Sie den Bereich und löschen Sie ihn dann, damit es nicht zu einer Speicherfragmentierung kommt. Dieser Algorithmus wird bei der Garbage Collection der neuen Generation verwendet, wobei vom Eden-Bereich in den From-Survivor-Bereich und dann in den To-Survivor-Bereich kopiert wird. Da es weniger überlebende Objekte gibt, wird beim Kopieren weniger Platz beansprucht.

3. Markierungs-Organisationsalgorithmus

Markieren Sie zuerst die Objekte, die gelöscht werden müssen, verschieben Sie alle überlebenden Objekte an ein Ende und dann Entfernen Sie alle nutzlosen Gegenstände. Im Gegensatz zur neuen Generation verfügt die alte Generation nach jedem GC über mehr überlebende Objekte und der Kopieralgorithmus beansprucht viel Speicher. Der „Mark-Organize“-Algorithmus spart Speicher, ohne eine Speicherfragmentierung zu verursachen.

Fünf Garbage-Collection-Timings

Verschiedene Generationen haben unterschiedliche GC-Mechanismen: Scavenge GC und Full GC.

Wenn der Eden-Bereich der neuen Generation voll ist und die neu generierten Objekte keinen Platz beantragen, wird Scavenge GC ausgelöst, um eine GC-Manipulation im Eden-Bereich durchzuführen, was offensichtlich nutzlos ist Objekte und schaffen Platz. Scavenge GC funktioniert nur auf der neuen Generation.

Wenn die alte Generation voll ist oder die persistente Generation voll ist oder die System.gc()-Methode explizit aufgerufen wird, wird die vollständige GC ausgelöst, um GC für alle Objektspeicherbereiche durchzuführen Je größer der Ressourcenverbrauch, desto weniger vollständige GC-Zeiten.

Sechs weitere Methoden

1.System.gc()

Informieren Sie die JVM Müll starten Der Kollektor und der Garbage Collector verwenden Daemon-Threads und starten möglicherweise nicht sofort. Der genaue Zeitpunkt, zu dem sie gestartet werden, kann nicht gesteuert werden. Darüber hinaus verbraucht viele Ressourcen, daher wird es im Allgemeinen nicht explizit aufgerufen.

2.finalize()

Objektbereichsmethode. Wird aufgerufen, nachdem die JVM bestätigt hat, dass auf ein Objekt nicht zugegriffen werden kann. Es kann nur einmal aufgerufen werden und wird normalerweise zum Freigeben von Verbindungsressourcen verwendet. Nach dem Aufruf dieser Methode fordert der Garbage Collector den vom Objekt belegten Speicherplatz nicht sofort zurück, da während der Ausführung dieser Methode möglicherweise erneut auf das Objekt zugegriffen wird. Stattdessen wird der vom Objekt belegte Speicherplatz erst zurückgefordert, nachdem dies bestätigt wurde Das Objekt ist während des nächsten GC-Bereichs immer noch nicht zugänglich.

Sieben Maßnahmen zur Reduzierung des GC-Overheads

  1. Vermeiden Sie die Verwendung statischer Variablen, da der Lebenszyklus statischer Variablen unterschiedlich ist von dem der Anwendung Auch wenn es längere Zeit nicht verwendet wird, belegt es dennoch Speicherplatz.

  2. Ressourcenverbindungen wie OutputStreamInputStreamConnectionSocket sollten sofort nach der Verwendung geschlossen und Ressourcen rechtzeitig freigegeben werden.

  3. Versuchen Sie, System.gc() nicht explizit aufzurufen, da diese Methode möglicherweise eine vollständige GC auslöst, was teuer ist.

  4. Reduzieren Sie die Verwendung temporärer Variablen, da die temporären Variablen nach der Ausführung der Methode zu Müll werden. Eine große Anzahl temporärer Variablen erhöht die Anzahl der GCs und den Systemverbrauch erhöhen.

  5. Nachdem die Objektreferenz abgeschlossen ist, geben Sie die Referenz rechtzeitig frei, um den Speicherplatz rechtzeitig zurückzugewinnen.

  6. Verwenden Sie so oft wie möglich veränderliche Objekte und reduzieren Sie die Anzahl der Verwendungen unveränderlicher Objekte.

  7. Versuchen Sie, Basistypvariablen anstelle der entsprechenden Wrapper-Klassen zu verwenden, da Basistypvariablen viel weniger Ressourcen beanspruchen als die entsprechenden Wrapper-Klassen.

  8. Vereinzelte Objekte erstellen und löschen. Da das gemeinsame Erstellen von Objekten viel Platz erfordert, wird wahrscheinlich eine vollständige GC ausgelöst, was den Systemverbrauch sofort erhöht. Das intensive Löschen von Objekten kann dazu führen, dass sofort eine große Anzahl nutzloser Objekte angezeigt wird, was auch eine vollständige GC auslösen kann.

Referenz:


     
     
     
     
     

Das obige ist der detaillierte Inhalt vonJava – detaillierte Erklärung des Garbage-Collection-Mechanismus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn