JVM Müllsammler

1. Übersicht

In diesem kurzen Tutorial zeigen wir die Grundlagen verschiedener JVM Garbage Collection (GC) -Implementierungen. Darüber hinaus erfahren Sie, wie Sie einen bestimmten Typ der Garbage Collection in unseren Anwendungen aktivieren.

2. Kurze Einführung in die Speicherbereinigung

Aus dem Namen geht hervor, dass sich Garbage Collection mit dem Suchen und Löschen des Mülls aus dem Speicher befasst. In der Realität verfolgt Garbage Collection jedoch jedes im JVM-Heap-Bereich verfügbare Objekt und entfernt nicht verwendete Objekte.

Mit einfachen Worten, GC arbeitet in zwei einfachen Schritten, die als Mark und Sweep bekannt sind:

  • Markieren - Hier identifiziert der Garbage Collector, welche Speicherelemente verwendet werden und welche nicht
  • Sweep - Dieser Schritt entfernt Objekte, die während der Markierungsphase identifiziert wurden

Vorteile:

  • Keine manuelle Speicherzuweisung / Freigabebehandlung, da nicht genutzter Speicherplatz automatisch von GC verarbeitet wird
  • Kein Aufwand für die Handhabung von Dangling Pointer
  • Automatische Speicherleckverwaltung ( GC allein kann nicht die vollständige Proof-Lösung für Speicherlecks garantieren, kümmert sich jedoch um einen Großteil davon)

Nachteile:

  • Da JVM die Erstellung / Löschung von Objektreferenzen verfolgen muss, erfordert diese Aktivität neben der ursprünglichen Anwendung mehr CPU-Leistung. Dies kann die Leistung von Anforderungen beeinträchtigen, für die ein großer Speicher erforderlich ist
  • Programmierer haben keine Kontrolle über die Planung der CPU-Zeit für die Freigabe nicht mehr benötigter Objekte
  • Die Verwendung einiger GC-Implementierungen kann dazu führen, dass die Anwendung unvorhersehbar gestoppt wird
  • Die automatische Speicherverwaltung ist nicht so effizient wie die ordnungsgemäße manuelle Speicherzuweisung / -freigabe

3. GC-Implementierungen

JVM verfügt über vier Arten von GC- Implementierungen:

  • Serial Garbage Collector
  • Paralleler Garbage Collector
  • CMS Garbage Collector
  • G1 Müllsammler

3.1. Serial Garbage Collector

Dies ist die einfachste GC-Implementierung, da sie grundsätzlich mit einem einzelnen Thread funktioniert. Infolgedessen friert diese GC- Implementierung alle Anwendungsthreads ein, wenn sie ausgeführt wird . Daher ist es keine gute Idee, es in Multithread-Anwendungen wie Serverumgebungen zu verwenden.

Auf der QCon 2012 gab es jedoch einen hervorragenden Vortrag von Twitter- Ingenieuren über die Leistung von Serial Garbage Collector - ein guter Weg, um diesen Collector besser zu verstehen.

Der Serial GC ist der Garbage Collector der Wahl für die meisten Anwendungen, für die keine geringen Pausenzeiten erforderlich sind und die auf Clients ausgeführt werden. Um Serial Garbage Collector zu aktivieren , können Sie das folgende Argument verwenden:

java -XX:+UseSerialGC -jar Application.java

3.2. Paralleler Garbage Collector

Dies ist der Standard- GC der JVM und wird manchmal als Durchsatzkollektoren bezeichnet. Im Gegensatz zu Serial Garbage Collector werden hier mehrere Threads zum Verwalten des Heapspeichers verwendet . Es friert aber auch andere Anwendungsthreads ein, während GC ausgeführt wird .

Wenn wir diesen GC verwenden , können wir maximale Garbage Collection- Threads und Pausenzeit, Durchsatz und Footprint (Heap-Größe) angeben .

Die Anzahl der Garbage Collector-Threads kann mit der Befehlszeilenoption -XX: ParallelGCThreads = gesteuert werden .

Das maximale Pausenzeitziel (Lücke [in Millisekunden] zwischen zwei GC ) wird mit der Befehlszeilenoption -XX: MaxGCPauseMillis = angegeben .

Das maximale Durchsatzziel (gemessen in Bezug auf die Zeit, die für die Speicherbereinigung aufgewendet wird, im Vergleich zu der Zeit, die außerhalb der Speicherbereinigung verbracht wird) wird durch die Befehlszeilenoption -XX: GCTimeRatio = angegeben.

Der maximale Heap-Footprint (die Menge an Heap-Speicher, die ein Programm während der Ausführung benötigt) wird mit der Option -Xmx angegeben.

Um Parallel Garbage Collector zu aktivieren , können Sie das folgende Argument verwenden:

java -XX:+UseParallelGC -jar Application.java

3.3. CMS Garbage Collector

Die CMS- Implementierung (Concurrent Mark Sweep) verwendet mehrere Garbage Collector-Threads für die Garbage Collection. Es wurde für Anwendungen entwickelt, die kürzere Garbage Collection-Pausen bevorzugen und es sich leisten können, Prozessorressourcen mit dem Garbage Collector zu teilen, während die Anwendung ausgeführt wird.

Einfach ausgedrückt, Anwendungen, die diese Art von GC verwenden, reagieren im Durchschnitt langsamer, reagieren jedoch nicht auf die Speicherbereinigung.

Ein kurzer Punkt, der hier zu beachten ist, ist, dass ein Aufruf der expliziten Speicherbereinigung, z. B. die Verwendung von System.gc (), während der gleichzeitige Prozess ausgeführt wird, zu einem Fehler / einer Unterbrechung im gleichzeitigen Modus führt, da dieser GC gleichzeitig ausgeführt wird .

Wenn mehr als 98% der Gesamtzeit für die CMS- Garbage Collection aufgewendet werden und weniger als 2% des Heaps wiederhergestellt werden, wird vom CMS- Collector ein OutOfMemoryError ausgelöst . Bei Bedarf kann diese Funktion deaktiviert werden, indem der Befehlszeile die Option -XX: -UseGCOverheadLimit hinzugefügt wird.

Dieser Kollektor verfügt auch über einen Modus, der als inkrementeller Modus bezeichnet wird und in Java SE 8 veraltet ist und möglicherweise in einer zukünftigen Hauptversion entfernt wird.

Um den CMS Garbage Collector zu aktivieren , können wir das folgende Flag verwenden:

java -XX:+UseParNewGC -jar Application.java

Ab Java 9 ist der CMS-Garbage Collector veraltet . Daher druckt JVM eine Warnmeldung, wenn wir versuchen, sie zu verwenden:

>> java -XX:+UseConcMarkSweepGC --version Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release. java version "9.0.1"

Darüber hinaus hat Java 14 die CMS-Unterstützung vollständig eingestellt:

>> java -XX:+UseConcMarkSweepGC --version OpenJDK 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; support was removed in 14.0 openjdk 14 2020-03-17

3.4. G1 Müllsammler

G1 (Garbage First) Garbage Collector wurde für Anwendungen entwickelt, die auf Multiprozessor-Computern mit großem Speicherplatz ausgeführt werden. Es ist seit JDK7 Update 4 und in späteren Versionen verfügbar .

Der G1- Kollektor ersetzt den CMS- Kollektor, da er leistungsfähiger ist.

Unlike other collectors, G1 collector partitions the heap into a set of equal-sized heap regions, each a contiguous range of virtual memory. When performing garbage collections, G1 shows a concurrent global marking phase (i.e. phase 1 known as Marking) to determine the liveness of objects throughout the heap.

After the mark phase is completed, G1 knows which regions are mostly empty. It collects in these areas first, which usually yields a significant amount of free space (i.e. phase 2 known as Sweeping). It is why this method of garbage collection is called Garbage-First.

To enable the G1 Garbage Collector, we can use the following argument:

java -XX:+UseG1GC -jar Application.java

3.5. Java 8 Changes

Java 8u20 hat einen weiteren JVM- Parameter eingeführt, um die unnötige Speichernutzung zu reduzieren, indem zu viele Instanzen derselben Zeichenfolge erstellt werden. Dies optimiert den Heapspeicher, indem doppelte Zeichenfolgenwerte in einem globalen einzelnen char [] -Array entfernt werden.

Dieser Parameter kann durch Hinzufügen von -XX: + UseStringDeduplication als JVM- Parameter aktiviert werden.

4. Fazit

In diesem kurzen Tutorial haben wir uns die verschiedenen Implementierungen der JVM Garbage Collection und ihre Anwendungsfälle angesehen.

Eine ausführlichere Dokumentation finden Sie hier.