Java GC: Warum zwei Überlebensregionen?

77

Für die JVM von Sun / Oracle habe ich gelesen, dass der GC-Algo die neue Generation in eine Eden-Region und zwei Überlebensregionen unterteilt. Ich frage mich, warum zwei Überlebensregionen und nicht nur eine? Die Algo kann zwischen Eden und nur einer Überlebensregion weiter Ping-Pong spielen (so wie es derzeit zwischen zwei Überlebensregionen der Fall ist). oder gibt es irgendwelche mängel bei diesem ansatz?

shrini1000
quelle
2
Interessant - würde es Ihnen etwas ausmachen, die Links zu veröffentlichen, zu denen Sie darüber gelesen haben? Ich denke, das würde der Frage helfen. Bearbeiten: Dieser Artikel scheint es zu beschreiben, nicht sicher, ob es das gleiche ist, das Sie gelesen haben.
Paul Bellora
Paul Bellora: Nicht dieser Link, aber ich habe ihn in mehreren Büchern und Artikeln gelesen. Werde diese Links bald veröffentlichen.
shrini1000
@ Paul Bellora Dies ist für Java 5, aber es erwähnt "zu" und "von" Überlebensräumen: oracle.com/technetwork/java/javase/…
shrini1000
Oh cool, danke für den Link - und nette Frage!
Paul Bellora

Antworten:

79

Ich glaube, dass die GC-Implementierung von JRockit eher so funktioniert, wie Sie es vorschlagen, mit nur einem einzigen Eden- und einem einzigen Überlebensraum, aber zitieren Sie mich nicht dazu.

Der Grund für die beiden Überlebensbereiche der HotSpot JVM besteht darin, dass weniger Fragmentierung erforderlich ist. Neue Objekte werden im Eden Space zugewiesen. Alles schön und gut. Wenn das voll ist, brauchst du einen GC. Töte also abgestandene Objekte und verschiebe lebende in einen Überlebensraum, wo sie eine Weile reifen können, bevor sie zur alten Generation befördert werden. Bisher noch gut. Das nächste Mal, wenn uns der Eden-Raum ausgeht, haben wir ein Rätsel. Der nächste GC kommt und räumt sowohl in Eden als auch in unserem Überlebensraum etwas Platz frei, aber die Räume sind nicht zusammenhängend. Also ist es besser zu

  1. Versuchen Sie, die Überlebenden von Eden in die Löcher im Überlebensraum einzupassen, die vom GC geräumt wurden?
  2. Verschieben Sie alle Objekte im Überlebensraum nach unten, um die Fragmentierung zu beseitigen, und bewegen Sie dann die Überlebenden hinein?
  3. Sagen Sie einfach "Scheiß drauf, wir bewegen sowieso alles" und kopieren Sie alle Überlebenden aus beiden Räumen in einen völlig separaten Raum - den zweiten Überlebensraum - und lassen Sie so einen sauberen Eden- und Überlebensraum zurück, wo Sie können Wiederholen Sie die Sequenz auf dem nächsten GC?

Suns Antwort auf die Frage ist offensichtlich.

Ryan Stewart
quelle
3
Es ist mir nicht klar. Welche Alternative verfolgt HotSpot JVM?
vz0
1
Vielen Dank für eine sehr klare und präzise Antwort. Wenn möglich, können Sie auch pl. Kommentar zu welcher Option verwendet JRockit?
shrini1000
Siehe IBMs Beschreibung: publib.boulder.ibm.com/infocenter/javasdk/v6r0/…
Joseph Lust
10
Ich finde diese Antwort falsch - der von Ihnen beschriebene Kopieralgorithmus ist falsch. Ein Kopier-GC kopiert alle Objekte aus dem "von" -Raum in den "nach" -Raum. Danach wechseln beide Räume die Rollen. Das heißt, die Zuweisung neuer Objekte erfolgt immer im "von" -Raum (während der "bis" -Raum immer leer ist), sodass keine Möglichkeit für Fragmentierungsprobleme besteht. Eine bessere Erklärung wäre, dass die Verwendung von 3 Leerzeichen den Speicher effizienter nutzt, wie hier beschrieben: stackoverflow.com/questions/21476348/…
Asher Saban
kann jemand mit der Option zwei (2) helfen? Was bedeutet "down" und die ganze Zeile hier . "Verschieben Sie alle Objekte im Überlebensraum nach unten, um die Fragmentierung zu beseitigen"
Vikash
24

Die Rolle von zwei Überlebensräumen wird nach dem Betrieb einer kleinen Müllabfuhr umgekehrt

Die zwei Überlebensräume. Diese enthalten Objekte, die mindestens eine kleinere Speicherbereinigung überlebt haben, aber eine weitere Chance erhalten haben, nicht mehr erreichbar zu sein, bevor sie zur alten Generation befördert werden. Nur einer von ihnen enthält Objekte, während der andere die meiste Zeit nicht verwendet wird.

Während des Betriebs einer kleinen Speicherbereinigung werden Objekte markiert, bei denen festgestellt wurde, dass es sich um Speicher handelt. Lebende Objekte im Eden, die die Sammlung überleben, werden in den nicht verwendeten Überlebensraum kopiert. Lebende Objekte im verwendeten Überlebensraum, die in der jungen Generation eine weitere Chance erhalten, zurückgefordert zu werden, werden ebenfalls in den nicht genutzten Überlebensraum kopiert. Schließlich werden lebende Objekte im verwendeten Überlebensraum, die als „alt genug“ eingestuft werden, zur alten Generation befördert.

Am Ende der kleinen Müllabfuhr tauschen die beiden Überlebensräume die Rollen. Der Eden ist völlig leer; Es wird nur ein Überlebensraum verwendet. und die Belegung der alten Generation ist leicht gewachsen. Da lebende Objekte während des Betriebs kopiert werden, wird diese Art von Garbage Collector als Kopier-Garbage Collector bezeichnet.

Quelle: oben sind die Auszüge aus Seite 83 von Java Performance von Charlie Hunt und Binu John.

Neeraj Singh
quelle
4

Junge Generation: Es ist ein Ort, an dem kurze Zeit gelebt und in zwei Räume unterteilt wurde:

Eden Space: Neue Objekte werden im Speicherpool zugewiesen. Die Annahme ist, dass die meisten Objekte dereferenziert werden und bald nach ihrer Erstellung nicht mehr erreichbar sind. Objekte, die nicht dereferenziert werden, werden vom Garbage Collector der neuen Generation in die Überlebensräume kopiert. Sie können in einigen Sonderfällen direkt in den Pool der alten Generation kopiert werden.

Überlebensräume: In diesen beiden kleinen Räumen befinden sich die überlebenden Objekte einer Müllsammlung der jungen Generation. Überlebende Objekte werden eine (kleine) Anzahl von Malen von einem Überlebenden in den anderen kopiert. Dies ermöglicht es, unsere stärker dereferenzierten Objekte zu ernten.

Alte Generation: Der größte Speicherpool, in dem die langlebigen Objekte aufbewahrt werden sollen. Objekte werden in diesen Pool kopiert, sobald sie die Überlebensräume verlassen.

Permamentgenerierung: Dieser ziemlich unbekannte Pool speichert die Informationen aller Klassen. Für die meisten Anwendungen ist keine Aufmerksamkeit erforderlich. Es muss möglicherweise für einige Anwendungen mit vielen Klassen angepasst werden. Möglicherweise ist auch etwas Aufmerksamkeit erforderlich, wenn die Anwendung Klassen dauerhaft lädt und entlädt.

Weitere Vorteile:

  • Speicherfragmentierung
  • Es verbessert die GC-Leistung

Weitere Informationen finden Sie unter den folgenden Links

http://www.scalingbits.com/javaprimer

http://java.sys-con.com/node/84695

Premraj
quelle
2

Alle aktuellen Antworten sprechen von Speicherfragmentierung. Dies ist auch ein weiterer Grund für Generationen in der GC.

Die Laufzeit zeichnet alle "alten Objekte" auf, die auf "neue Objekte" verweisen. Dies erfolgt jedes Mal, wenn ein "Zeiger" -Feld aktualisiert wird. Wenn dann ein "kleiner" GC durchgeführt wird, müssen nur "neue" Objekte gescannt werden.

Im Laufe der Jahre hat sich herausgestellt, dass es nicht ausreicht, nur „neu“ und „alt“ zu haben, und es ist gut, eine dritte Generation zu haben, die „mittleren Alters“ ist.

Ian Ringrose
quelle
1

Was sind die Vor- und Nachteile des Kopierens aller Instanzen einer Generation von einem Raum in einen anderen gegenüber dem Kopieren in der Reihenfolge der Speicheradressen zum Beginn des Raums einer Generation? Das Verarbeiten von Elementen in der richtigen Reihenfolge würde wahrscheinlich das Hinzufügen eines zusätzlichen Zeigers pro Element erfordern, würde jedoch die Notwendigkeit eines der "Überlebenden" -Räume beseitigen.

Superkatze
quelle
0

Zwei Überlebende implementieren den Markierungs- und Kopieralgorithmus. Diese werden in der GC für die jüngere Generation verwendet. Wie von Ryan in Option 3 hier erwähnt

Geben Sie hier die Bildbeschreibung ein

Vikash
quelle
Für eine detailliertere Erklärung lesen Sie es developerjournal.in/…
Nasif Md. Tanjim
0

Heapspeicher in Java Java-Objekte, die in einem Bereich erstellt wurden, der als Heapspeicher bezeichnet wird. Der Heapspeicher wird beim Start der JVM erstellt. Der Heapspeicher wird beim Ausführen einer Java-Anwendung vergrößert oder verkleinert. Wenn der Heapspeicher voll ist, entfernt der Garbage Collector die nicht verwendeten Objekte, sodass der Garbage Collector Platz für neue Objekte schafft.

Der Heapspeicher ist in zwei Bereiche (oder Generationen) unterteilt, die aufgerufen werden

1. junger Raum. 2. Alter Raum.

1. Im jungen Raum gibt es Eden-Raum für neues Objekt und es gibt zwei Überlebensräume (von und nach). Diese beiden Überlebensräume sind immer gleich groß.

2.Überlebende Räume werden zum Speichern von Überlebensobjekten verwendet. Wenn der junge Raum voll ist, entfernt der Garbage Collector die nicht verwendeten Objekte, indem er eine spezielle junge Sammlung ausführt, in der alle Objekte, die lange genug im jungen Raum gelebt haben, in den verschoben werden alter Raum, wodurch der junge Raum für mehr Objektzuweisung frei wird.

3.Wenn der Eden-Raum voll ist, wird GC ausgeführt. Wenn sich Objekte in diesem Eden-Raum befinden, werden diese in den Survivor-Raum verschoben.

4. Im jungen Raum verwendet GC normalerweise den Kopieralgorithmus, der schnell ist. Jedes Mal, wenn Überlebensobjekte in einen der Überlebensräume kopiert werden.

5.Wenn der Survivor Space voll ist, werden die restlichen Live-Objekte direkt in den Old Space kopiert.

6. Im alten Raum verwendet GC normalerweise den Mark-Compact-Algorithmus, der langsam ist, aber weniger Speicher benötigt.

7.Wenn der alte Raum voll wird, wird dort Müll gesammelt, ein Prozess, der als alte Sammlung bezeichnet wird. Im alten Raum bleiben Objekte mit langer Lebensdauer dort.

8. Außerhalb des Speichers wird kein Platz für neues Objekt vorhanden sein, selbst wenn die GC für den ALTEN oder den Perm-Teil durchgeführt wird.

9.Objekt wird während der Garbage Collection verschoben: eden -> Survivor -> tenured (alter Raum)

ASR
quelle