Technologieaustausch

[JVM-Grundlagen] Einführung in Java Garbage Collector

2024-07-11

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Garbage Collector (Implementierung des Garbage Collection-Algorithmus)

Der Garbage Collector ist die spezifische Implementierung des Garbage Collection-Algorithmus . Da der Garbage Collector zusätzlich zu G1 (das sowohl die neue als auch die alte Generation steuern kann) in die junge und die alte Generation unterteilt ist,Die Garbage Collectors der neuen Generation und der alten Generation müssen entsprechend den Hotspot-Anforderungen paarweise verwendet werden.(Sie müssen die entsprechende Kombination entsprechend der JDK-Version auswählen)

Die spezifische Kombinationsbeziehung ist wie folgt:

Fügen Sie hier eine Bildbeschreibung ein

Im zugrunde liegenden JVM-Quellcode ruft der CMS-Recycler in einigen Sonderfällen den Serial Old-Recycler auf.

Arthas sieht sich den verwendeten Müllsammler an

Sie können nicht direkt sehen, welcher Garbage Collector verwendet wird, Sie können ihn nur anhand des Algorithmus ableiten.

Fügen Sie hier eine Bildbeschreibung ein

Junge Generation – Serien-Garbage Collector

Seriell ist einSingle-Threaded-Seriensammlung der jungen GenerationDer Müllsammler.

Fügen Sie hier eine Bildbeschreibung ein

Recycling von Zeitaltern und Algorithmen

  • junge Generation
  • Replikationsalgorithmus

Vorteil

Hervorragender Durchsatz auf einem einzigen CPU-Prozessor

Mangel

Der Durchsatz unter Multi-CPU ist nicht so gut wie bei anderen Garbage Collectors (Single-Threaded, nur eine CPU verwendend). Wenn der Heap zu groß ist, wartet der Benutzer-Thread lange.

Anwendbare Szene

In Java geschriebene Client-Programme oder Szenarien mit begrenzter Hardwarekonfiguration (nicht viele CPU-Kerne)

wie benutzt man

-XX: UseSerialGC: Sowohl die neue als auch die alte Generation verwenden den seriellen Kollektor.

Alte Generation – SeriellAlter Garbage Collector

SerialOld ist die alte Generation des Serial Garbage CollectorsSingle-Threaded-Seriensammlung

Fügen Sie hier eine Bildbeschreibung ein

Recycling von Zeitaltern und Algorithmen

  • hohes Alter
  • Mark-Collation-Algorithmus

Vorteil

Hervorragender Durchsatz auf einem einzigen CPU-Prozessor

Mangel

Der Durchsatz unter Multi-CPU ist nicht so gut wie bei anderen Garbage Collectors. Wenn der Heap zu groß ist, wartet der Benutzerthread lange.

Anwendbare Szene

Wird mit dem Serial Garbage Collector oder in CMS-Sonderfällen verwendet

wie benutzt man

-XX: UseSerialGC: Sowohl die neue als auch die alte Generation verwenden den seriellen Kollektor.

Junge Generation – ParNeuer Müllsammler

Der ParNew Garbage Collector ist im WesentlichenOptimierung von Serial unter mehreren CPUs, wobei Multithreading für die Speicherbereinigung verwendet wird

Fügen Sie hier eine Bildbeschreibung ein

Recyclingalter und Algorithmus:

  • junge Generation
  • Replikationsalgorithmus

Vorteil

  • Kürzere Pausenzeiten bei Multi-CPU-Prozessoren

Mangel

  • Der Durchsatz und die Pausenzeit sind nicht so gut wie bei G1, daher wird dies nach JDK9 nicht empfohlen

Anwendbare Szene

  • In JDK8 und früheren Versionen wird es in Verbindung mit dem CMS-Garbage Collector der alten Generation verwendet.

wie benutzt man

  • -XX: UseParNewGC: Die neue Generation verwendet den ParNew-Kollektor und die alte Generation verwendet den seriellen Kollektor.

Fügen Sie hier eine Bildbeschreibung ein

CMS-Garbage Collector der alten Generation (Concurrent Mark Sweep).

Der CMS-Garbage Collector konzentriert sich auf die Pausenzeit des Systems (um STW zu minimieren und die Benutzererfahrung zu optimieren).Ermöglichen Sie die gleichzeitige Ausführung von Benutzer-Threads und Garbage-Collection-Threads in bestimmten Schritten, wodurch die Wartezeit von Benutzerthreads verkürzt wird.

Recycling von Zeitaltern und Algorithmen

  • hohes Alter
  • Mark-and-Sweep-Algorithmus

Vorteil

  • Die Pausenzeit des Systems aufgrund der Speicherbereinigung ist kürzer und die Benutzererfahrung ist besser.

Mangel

1. Speicherfragmentierungsproblem

2. Verschlechterungsproblem (in einigen bestimmten Fällen wird es zu einem Single-Thread-Kollektor wie SerialOld degenerieren)

3. Problem mit schwimmendem Müll (einige Abfälle können während des Recyclingprozesses nicht recycelt werden)

Anwendbare Szene

Szenarien in großen Internetsystemen, in denen Benutzer große Datenmengen und hohe Frequenzen anfordern, z. B. Bestellschnittstellen, Produktschnittstellen usw.

verwenden

XX: UseConcMarkSweepGC, können Sie die Sammler der jungen Generation bzw. der alten Generation einstellen.

Fügen Sie hier eine Bildbeschreibung ein

Fügen Sie hier eine Bildbeschreibung ein

CMS-Ausführungsschritte

  1. Erstmarkierung, Anreißen in kürzester ZeitObjekte, auf die sich GC Roots direkt beziehen kann
  2. gleichzeitige Markierung, Markieren Sie alle Objekte , muss der Benutzerthread nicht angehalten werden. (Obwohl die gleichzeitige Markierung zusammen mit dem Benutzerthread ausgeführt wird, wirkt sich dies auch auf den Benutzerthread aus, wenn die durch die gleichzeitige Markierung belegten Ressourcen hoch sind.)
  3. Hinweis (Parallelität): Da sich einige Objekte während der gleichzeitigen Markierungsphase ändern, kommt es zu einer falschen Beschriftung (das verwendete Objekt war ursprünglich lebendig, aber nach der Markierung wurde es vom Benutzerthread nicht mehr verwendbar, was zu einer falschen Beschriftung führte) und zu einer fehlenden Beschriftung ( Weil Es ist gleichzeitig, einige Objekte wurden möglicherweise gerade vom Benutzerthread erstellt, was zu fehlenden Tags führt) und anderen Situationen und müssen neu markiert werden.
  4. Gleichzeitige Bereinigung, tote Objekte bereinigen, Benutzer-Threads müssen nicht angehalten werden.

Hinweis: STW wird nur während der Erstmarkierungs- und Neumarkierungsphase angezeigt.

Fügen Sie hier eine Bildbeschreibung ein

Mangel:

1. CMS verwendet einen Mark-and-Clear-Algorithmus. Nach Abschluss der Speicherbereinigung wird eine große Anzahl von Speicherfragmenten angezeigt, um die Zuordnung von Objekten nicht zu beeinträchtigen.CMS wird während der vollständigen GC defragmentiert. . Dadurch wird der Benutzerthread angehalten.Sie können den Parameter -XX:CMSFullGCsBeforeCompaction=N (Standard 0) verwenden, um den vollständigen GC N-mal anzupassen, bevor Sie ihn aussortieren.

2. Der während des gleichzeitigen Bereinigungsprozesses erzeugte „schwebende Müll“ kann nicht verarbeitet werden und es kann keine vollständige Müllsammlung erreicht werden (während dieses Bereinigungsprozesses hat der Benutzerthread einige Objekte gleichzeitig erstellt, diese wurden jedoch nicht bald wieder verwendet. Diese Objekte sind nicht vorhanden Bei dieser Bereinigung recycelt und muss bis zur nächsten Bereinigung warten, weshalb es sich um schwimmenden Müll handelt.

3. Wenn in der alten Generation nicht genügend Speicher zum Zuweisen von Objekten vorhanden ist, degeneriert CMS zu Serial Old Single-Thread und recycelt die alte Generation.

Anzahl gleichzeitiger Threads:

Die Anzahl der Threads beim Ausführen der gleichzeitigen Phase im CMS kann übergeben werden-XX:ConcGCThreadsParametereinstellung, vom System berechnet, die Berechnungsformel lautet(-XX:ParallelGCThreads定义的线程数 3) / 4, ParallelGCThreads ist die Anzahl der parallelen Threads nach der STW-Pause

ParallelGCThreads wird durch die Anzahl der Prozessorkerne bestimmt:

1. Wenn die Anzahl der CPU-Kerne weniger als 8 beträgt, ist ParallelGCThreads = Anzahl der CPU-Kerne

2. Ansonsten ParallelGCThreads = 8 (Anzahl der CPU-Kerne – 8)*5/8

Es gibt 12 logische Prozessoren auf meinem Computer, also ParallelGCThreads = 8 (12 - 8) * 5/8 = 10, ConcGCThreads = (-XX: Die Anzahl der durch ParallelGCThreads 3 definierten Threads) / 4 = (10 3) / 4 = 3

Fügen Sie hier eine Bildbeschreibung ein

Endlich könnt ihr dieses Bild machen:

Fügen Sie hier eine Bildbeschreibung ein

Die gleichzeitigen Markierungs- und gleichzeitigen Reinigungsphasen werden parallel mithilfe von drei Threads verarbeitet. Die Neumarkierungsphase wird mit 10 Threads verarbeitet. Da die Anzahl der CPU-Kerne begrenzt ist, wirkt sich die gleichzeitige Phase auf die Leistung der Benutzer-Thread-Ausführung aus.

Fügen Sie hier eine Bildbeschreibung ein

Paralleler Müllsammler der jungen Generation

Parallel Scavenge istJDK8-Standard-Garbage Collector der jungen Generation,MultithreadingParallelsammlungKonzentrieren Sie sich auf den Systemdurchsatz .Um den Durchsatz zu erhöhen, wird PSPassen Sie die Heap-Speichergröße automatisch an (passen Sie die Speichergröße der neuen Generation, der alten Generation und den Hochstufungsschwellenwert an).

Fügen Sie hier eine Bildbeschreibung ein

Recycling von Zeitaltern und Algorithmen

  • junge Generation
  • Replikationsalgorithmus

Vorteil

  • Der Durchsatz ist hoch und es unterstützt die manuelle Einstellung von Parametern zur Steuerung des Durchsatzes. Um den Durchsatz zu verbessern, passt die virtuelle Maschine die Parameter des Heaps dynamisch an (der Benutzer muss nur den Durchsatz festlegen und keine anderen Parameter wie die Speichergröße festlegen).

Mangel

  • Es gibt keine Garantie für eine einzelne Pausenzeit, es wird jedoch die Einstellung der STW-Zeit unterstützt.

Anwendbare Szene

  • Hintergrundaufgaben erfordern keine Benutzerinteraktion und erzeugen in der Regel eine große Anzahl von Objekten.Zum Beispiel: Big-Data-Verarbeitung, Export großer Dateien

Gemeinsame Parameter

Parallel Scavenge ermöglicht die manuelle Einstellung der maximalen Pausenzeiten und des Durchsatzes. Oracle-Beamte empfehlen, bei Verwendung dieser Kombination den maximalen Heap-Speicher nicht festzulegen. Der Garbage Collector passt die Speichergröße automatisch basierend auf der maximalen Pausenzeit und dem maximalen Durchsatz an.

  • maximale Pausenzeit,-XX:MaxGCPauseMillis=n Legen Sie die maximale Pause in Millisekunden für jede Garbage Collection fest
  • Durchsatz,-XX:GCTimeRatio=n Stellen Sie den Durchsatz auf n ein (Benutzer-Thread-Ausführungszeit = n/(n 1))
  • Speichergröße automatisch anpassen, -XX: UseAdaptiveSizePolicyMit dieser Einstellung kann der Garbage Collector die Speichergröße basierend auf dem Durchsatz und den maximalen Pausen-Millisekunden automatisch anpassen. Dieser Parameter ist standardmäßig aktiviert (Oracle empfiehlt, bei Verwendung der PS-Kombination den maximalen Wert des Heap-Speichers nicht festzulegen und den Garbage Collector automatisch anpassen zu lassen )

Hinweis: Die beiden Indikatoren für maximale Pausenzeit und Durchsatz stehen im Konflikt. Der Garbage Collector wird sein Bestes tun, um die maximale Pausenzeit einzuhalten (manchmal ist sie zu klein eingestellt und kann nicht eingehalten werden, und die festgelegte maximale Pausenzeit wird überschritten). , was den Durchsatz opfert.Wenn Sie die maximale Pausenzeit und den Durchsatz gleichzeitig festlegen möchten, müssen Sie mehr Tests durchführen, um sie besser zu koordinieren.

Alte Generation – paralleler alter Müllsammler

Parallel Old ist eine Version der alten Generation, die für den Parallel Scavenge-Kollektor entwickelt wurde und eine gleichzeitige Multithread-Sammlung nutzt.

Fügen Sie hier eine Bildbeschreibung ein

Recycling von Zeitaltern und Algorithmen

  • hohes Alter
  • Mark-Collation-Algorithmus (eigentlich Mark-Clearing-Sortierung)

Vorteil

  • Die gleichzeitige Erfassung ist unter Multi-Core-CPUs effizienter

Mangel

  • Die Pausenzeit wird länger

Anwendbare Szene

  • Wird mit Parallel Scavenge verwendet

wie benutzt man

JDK8 legt Parameter fest, um diesen Recycler standardmäßig zu verwenden.

Parameter:-XX: UseParallelGC oder-XX: UseParallelOldGCSie können die Kombination Parallel Scavenge Parallel Old verwenden.
Fügen Sie hier eine Bildbeschreibung ein

Fügen Sie hier eine Bildbeschreibung ein

prüfen

-XX: PrintFlagsFinal: Sie können beim Programmstart die Endwerte aller Konfigurationselemente ausdrucken. Sie können überprüfen, ob die automatische Anpassungsfunktion aktiviert ist.

Fügen Sie hier eine Bildbeschreibung ein

Fügen Sie hier eine Bildbeschreibung ein

Fügen Sie hier eine Bildbeschreibung ein

Fügen Sie hier eine Bildbeschreibung ein

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 垃圾回收器案例3
 */
//-XX: UseSerialGC -Xmn1g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc -XX: PrintFlagsFinal
//-XX: UseParNewGC  -Xmn1g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc
//-XX: UseConcMarkSweepGC
//-XX: UseG1GC   -Xmn8g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc MaxGCPauseMillis
//-XX: PrintFlagsFinal  -XX:GCTimeRatio = 19  -XX:MaxGCPauseMillis=10 -XX: UseAdaptiveSizePolicy
public class GcDemo2 {

    public static void main(String[] args) throws IOException {
        int count = 0;
        List