Garbage Collectors Algorithmen
Garbage Collectors haben typischerweise die folgenden Ziele (leichter gesagt als getan)
- Sehr kurze „stop the world pauses“ mit einem Ziel von ein paar Millisekunden
- Pausenzeiten erhöhen sich nicht mit einem Heap, Live-Set, oder Root-.Set-Größe
- Handhabung von Heap-Größen von wenigen MBs bis zu vielen TBs
- Hohe Gleichzeitigkeit – Alle schweren Arbeiten werden erledigt, während Java-Threads weiter ausgeführt werden
- Hoher Durchsatz
- Einfach zu tunen
Garbage Collectors
Daten im Heap werden in mehrere Allokationsregionen (oder Generationen) aufgeteilt, die auf der Grundlage des Objektalters (d. h. der Anzahl der überlebten GCs) getrennt gehalten werden.d. h. der Anzahl der überlebten GC-Iterationen). Einige Kollektoren sind eingenerational, andere verwenden zwei Generationen: (1) die Young Generation (weiter unterteilt in Eden und zwei Survivor-Regionen) und (2) die Old (oder Tenured) Generation.
Quelle: Blog von Ionut Balosin
Zwei Generationskollektoren:
Serial GC – Der Algorithmus verwendet einen einzigen Thread, um die gesamte Garbage Collection durchzuführen, was ihn relativ effizient macht, da es keinen Kommunikations-Overhead zwischen den Threads gibt. Er eignet sich am besten für Maschinen mit einem Prozessor, da er die Vorteile von Multiprozessor-Hardware nicht nutzen kann.
Throughput (Parallel) GC – Dieser Algorithmus verwendet Mark-Copy in der Young Generation und Mark-Sweep-Compact in der Old Generation. Sowohl Young als auch Old Collections lösen Stop-the-World-Ereignisse aus, wodurch alle Anwendungsthreads angehalten werden, um die Garbage Collection durchzuführen. Beide Kollektoren führen die Markierungs- und Kopier-/Kompaktierungsphasen unter Verwendung mehrerer Threads durch, daher der Name „Parallel“.
Der parallele Garbage Collector eignet sich für Multi-Core-Maschinen, wenn das primäre Ziel die Erhöhung des Durchsatzes ist. Ein höherer Durchsatz wird durch die effizientere Nutzung der Systemressourcen erreicht:
- während der Sammlung reinigen alle Kerne den Müll parallel, was zu kürzeren Pausen führt
- zwischen den Müllsammelzyklen verbraucht keiner der Kollektoren irgendwelche Ressourcen
Garbage First (G1) GC – Dieser Kollektor ist ein Garbage Collector im Server-Stil, der für Multiprozessor-Maschinen mit großem Speicher gedacht ist. Er erfüllt die Ziele für die Pausenzeit der Garbage Collection (GC) mit hoher Wahrscheinlichkeit und erreicht gleichzeitig einen hohen Durchsatz.
- Der G1-Collector verfolgt einen anderen Ansatz in Bezug auf das Heap-Speicher-Modell. Der Heap ist in eine Reihe von gleich großen Heap-Regionen unterteilt, die jeweils einen zusammenhängenden Bereich des virtuellen Speichers darstellen.
- Bestimmten Regionssätzen werden dieselben Rollen (eden, survivor, old) zugewiesen wie bei den älteren Kollektoren, aber es gibt keine feste Größe für sie.
- Die Regionsgröße wird von der JVM beim Start ausgewählt. Die JVM zielt im Allgemeinen auf etwa 2000 Regionen mit einer Größe von 1 bis 32 MB ab. Der G1-Kollektor verfolgt einen anderen Ansatz
Weitere Einzelheiten finden Sie unter Erste Schritte mit der G1 GC
Uni generational collectors:
Shenandoah GC – Shenandoah ist der Garbage-Collector mit geringer Pausenzeit, der die GC-Pausenzeiten reduziert, indem er mehr Garbage-Collection-Arbeiten gleichzeitig mit dem laufenden Java-Programm durchführt. Shenandoah führt den Großteil der GC-Arbeiten gleichzeitig aus, einschließlich der gleichzeitigen Verdichtung, was bedeutet, dass seine Pausenzeiten nicht mehr direkt proportional zur Größe des Heaps sind. Das Garbage Collecting eines 200 GB Heaps oder eines 2 GB Heaps sollte ein ähnlich niedriges Pausenverhalten aufweisen.
Weitere Details finden Sie unter Implementierungsdetails im Wiki
Z GC – ZGC ist ein gleichzeitiger, auf einer einzigen Generation basierender, regionsbasierter, NUMA-bewusster, verdichtender Kollektor. Sobald der verfügbare Java-Heap erschöpft ist, wird die JVM heruntergefahren. Entwickelt für interne JDK-Tests, kann aber in zwei Situationen nützlich sein
- Sehr kurzlebige Programme
- Programme werden sorgfältig geschrieben, um Speicher wiederzuverwenden und nie neue Zuweisungen durchzuführen