Java Virtual Machine - Laufzeitdatenbereiche
Die JVM-Spezifikation definiert bestimmte Laufzeitdatenbereiche, die während der Ausführung des Programms benötigt werden. Einige davon werden beim Start der JVM erstellt. Andere sind lokal für Threads und werden nur erstellt, wenn ein Thread erstellt wird (und zerstört, wenn der Thread zerstört wird). Diese sind unten aufgeführt -
PC-Register (Programmzähler)
Es ist für jeden Thread lokal und enthält die Adresse des JVM-Befehls, den der Thread gerade ausführt.
Stapel
Es ist für jeden Thread lokal und speichert Parameter, lokale Variablen und Rücksprungadressen während Methodenaufrufen. Ein StackOverflow-Fehler kann auftreten, wenn ein Thread mehr Stapelspeicherplatz als zulässig benötigt. Wenn der Stapel dynamisch erweiterbar ist, kann er dennoch OutOfMemoryError auslösen.
Haufen
Es wird von allen Threads gemeinsam genutzt und enthält Objekte, Metadaten, Arrays usw. von Klassen, die zur Laufzeit erstellt werden. Es wird beim Start der JVM erstellt und beim Herunterfahren der JVM zerstört. Sie können die Menge an Heap, die Ihre JVM vom Betriebssystem anfordert, mithilfe bestimmter Flags steuern (dazu später mehr). Es muss darauf geachtet werden, nicht zu wenig oder zu viel Speicher zu beanspruchen, da dies wichtige Auswirkungen auf die Leistung hat. Darüber hinaus verwaltet der GC diesen Raum und entfernt kontinuierlich tote Objekte, um den Raum freizugeben.
Methodenbereich
Dieser Laufzeitbereich ist allen Threads gemeinsam und wird beim Start der JVM erstellt. Es speichert klassenbezogene Strukturen wie den Konstantenpool (dazu später mehr), den Code für Konstruktoren und Methoden, Methodendaten usw. Das JLS gibt nicht an, ob in diesem Bereich Müll gesammelt werden muss, und daher Implementierungen des JVM ignoriert möglicherweise GC. Darüber hinaus kann dies gemäß den Anforderungen der Anwendung erweitert werden oder nicht. Das JLS schreibt diesbezüglich nichts vor.
Konstanter Laufzeitpool
Die JVM verwaltet eine Datenstruktur pro Klasse / Typ, die als Symboltabelle (eine ihrer vielen Rollen) fungiert, während die geladenen Klassen verknüpft werden.
Native Method Stacks
Wenn ein Thread eine native Methode aufruft, betritt er eine neue Welt, in der die Strukturen und Sicherheitsbeschränkungen der Java Virtual Machine ihre Freiheit nicht mehr beeinträchtigen. Eine native Methode kann wahrscheinlich auf die Laufzeitdatenbereiche der virtuellen Maschine zugreifen (dies hängt von der nativen Methodenschnittstelle ab), kann aber auch alles andere tun, was sie will.
Müllabfuhr
Die JVM verwaltet den gesamten Lebenszyklus von Objekten in Java. Sobald ein Objekt erstellt wurde, muss sich der Entwickler nicht mehr darum kümmern. Falls das Objekt tot wird (dh es gibt keinen Hinweis mehr darauf), wird es vom GC mithilfe eines der vielen Algorithmen - serieller GC, CMS, G1 usw. - aus dem Heap ausgeworfen.
Während des GC-Prozesses werden Objekte im Speicher verschoben. Daher können diese Objekte während des Prozesses nicht verwendet werden. Die gesamte Anwendung muss für die Dauer des Prozesses gestoppt werden. Solche Pausen werden als "Stop-the-World" -Pausen bezeichnet und sind ein enormer Aufwand. GC-Algorithmen zielen hauptsächlich darauf ab, diese Zeit zu verkürzen. Wir werden dies in den folgenden Kapiteln ausführlich erörtern.
Dank des GC sind Speicherlecks in Java sehr selten, können aber auftreten. In den späteren Kapiteln werden wir sehen, wie ein Speicherverlust in Java erstellt wird.