© Swill Klitch/Shutterstock.com
Shenandoah und ZGC

Kurze Pause


Mit Shenandoah und ZGC gibt es im OpenJDK erstmals zwei Low-Pause Garbage Collectors, die die berüchtigten Pausenzeiten von Java-Anwendungen auf Millisekunden beschränken. Wir stellen die Arbeitsweise der beiden Collectors vor, messen mit Hilfe einer praxisnahen Benchmark, ob die Collectors halten, was sie versprechen, und diskutieren, wie sich Shenandoah und ZGC voneinander abgrenzen.

Zu den dynamischsten Gebieten des OpenJDK zählen derzeit die Garbage Collectors. Gab es 20 Jahre nach Einführung von Java mit SerialGC, ParallelGC, CMS und G1 lediglich vier Collectors, sind seit Java 11 mit ZGC und Shenandoah gleich zwei neue hinzugekommen. Beides sind Low-Pause Collectors, die Anwendungen nur wenige Millisekunden unterbrechen und den Großteil ihrer Aktivitäten nebenläufig zu den Anwendungsthreads ausführen. Das ist ein Novum im OpenJDK: Vergleichbare Produkte wie C4 von Azul waren in der Vergangenheit nur auf kommerzieller Basis verfügbar.

In der Literatur [1], [2] wurden Shenandoah und ZGC in der Vergangenheit separat behandelt, ohne ihre Funktionsweise zueinander in Bezug zu setzen. Wir verfolgen einen anderen Ansatz und arbeiten heraus, dass die beiden Collectors auf demselben Prozessmodell basieren.

Grundlagen

Objekte werden in Java in einem spezifischen Bereich, dem Heap, gespeichert. Ein Objekt heißt lebend, wenn die Anwendung darauf zugreifen kann. Objekte, die für die Applikation nicht erreichbar sind, werden als Garbage bezeichnet. Ein Garbage Collector (GC) hat die Aufgabe, Garbage zu identifizieren und zu recyceln, d. h. den von ihm belegten Speicherplatz wieder verfügbar zu machen. Ein GC ist regionenbasiert, wenn er den Heap in kleinere Bereiche (Regionen) unterteilt, die separat recycelt werden können.

Ein GC heißt parallel, wenn er seine Aufgaben auf mehrere parallel arbeitende Threads verteilt, er heißt concurrent oder nebenläufig, wenn die Threads des GCs und der Anwendung gleichzeitig ausgeführt werden. Hält ein GC die Anwendung an, spricht man von Stop the World (STW), die Anwendungsunterbrechung wird als Pause oder Latenz bezeichnet.

Eigenschaften von ZGC und Shenandoah

ZGC wurde von Oracle zunächst proprietär für das eigene JDK entwickelt, aber Ende 2017 in das OpenJDK überführt und in Java 11 freigegeben. Shenandoah (benannt nach dem gleichnamigen Nationalpark in den USA) wird seit 2013von Red Hat entwickelt und ist seit Java 12 Teil des OpenJDK. In Release 13 wurde Version 2.0 veröffentlicht, die weitreichende konzeptionelle Änderungen umfasst (Eliminierung des Extraworts zur Speicherung des Forward Pointers, Ersetzen der Read und Write Barriers durch eine Load Barrier).

Die vorliegende Darstellung bezieht sich auf Shenandoah 2.x und basiert bei beiden Collectors auf Java 14. Die wesentlichen Eigenschaften der Collectors sind die folgenden:

  • Pausenzeiten im Millisekundenbereich, auch bei Terabyte-Heaps

  • die Pausenzeit ist unabhängig von der Größe des Heap

  • Parallele und nebenläufige Verarbeitung in allen GC-Phasen

  • regionenbasiert, keine Generationen

  • Unterstützung von Concurrent Class Unloading und Uncommit Memory

Die Collectors zeichnen sich ferner durch Anwenderfreundlichkeit aus, da kein aufwendiges Konfigurieren nötig ist, um ein gutes Verhältnis von Durchsatz und kurzen Pausenzeiten zu erzielen.

GC-Phasen und Barrieren

Garbage Collectors arbeiten zyklisch. Ein Zyklus besteht bei Shenandoah und ZGC im Kern aus den Phasen Markierung, Evakuierung und Remapping (Abb. 1).

ellinger_shenandoah_1.tif_fmt1.jpgAbb. 1: Phasen und Barrieren

Die Phasen werden zum größten Teil nebenläufig zur Anwendung ausgeführt. Innerhalb eines Zyklus gibt es bei Shenandoah vier und bei ZGC drei Pausen, die in der Regel jeweils etwa 1 ms dauern.

Die Integrität der Anwendung, die nebenläufig zum GC auf dem Heap operiert, wird durch Barrieren sichergestellt. Eine Barriere ist Programmcode, der vom Hotspot-Compiler generiert und automatisch in den Anwendungscode eingebettet wird. Shenandoah und ZGC verwenden eine Mark und eine Load Barrier, die entsprechend der jeweiligen Phase ausgeführt werden. In den folgenden Abschnitten erläutern wir die Aufgaben der Phasen und ihr Zusammenspiel mit den Barrieren.

Markierung

Die Markierung ermittelt durch Traversieren des Objektgraphen die lebenden Objekte und den von ihnen belegten Speicherplatz. Anhand dieser Daten wählt der GC Regionen, die besonders viel Garbage enthalten, zum Recyceln aus (Region 1 in Abb. 2). Um Objekte nicht mehrfach zu verarbeiten, markiert der GC die erfassten Objekte mit Hilfe einer Bitmap. ZGC setzt zusätzlich ein Markierun...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang