Der Lademechanismus ist der Prozess, bei dem die JVM die Klassendatei in den Speicher lädt, die Daten überprüft, konvertiert, analysiert und initialisiert und schließlich einen Java-Typ bildet, der direkt sein kann Wird von der JVM verwendet.
Eine Klasse beginnt mit dem Laden in den Speicher der virtuellen Maschine, bis sie aus dem Speicher entladen wird. Ihr Lebenszyklus umfasst: Laden, Überprüfung, Vorbereitung, Lösung. Es gibt sieben Phasen: Initialisierung, Verwendung und Entladen. wobei die drei Teile Verifizierung, Vorbereitung und Analyse gemeinsam als Links bezeichnet werden.
Die Reihenfolge der fünf Phasen des Ladens (Ladens), Verifizierens, Vorbereitens, Initialisierens und Entladens ist festgelegt. Der Ladevorgang der Klasse muss in dieser Reihenfolge beginnen Die Parsing-Phase ist nicht unbedingt erforderlich; sie kann in einigen Fällen nach der Initialisierung für die dynamische Laufzeitbindungsfunktion gestartet werden. Es ist zu beachten, dass diese Phasen normalerweise gemischt ausgeführt werden und normalerweise während der Ausführung einer Phase eine andere Phase aufrufen oder aktivieren.
Die Ladephase ist eine Phase im „Klassenlademechanismus“. Diese Phase wird üblicherweise auch „Laden“ genannt und umfasst hauptsächlich:
1. Holen Sie sich den binären Bytestream, der diese Klasse definiert, über den „vollständigen Namen der Klasse“
2. Konvertieren Sie die durch den Bytestream dargestellte statische Speicherstruktur in Laufzeitdaten Bereichsstruktur
3. Generieren Sie ein java.lang.Class-Objekt, das diese Klasse im Java-Heap als Zugriffseintrag für diese Daten im Methodenbereich darstellt
Die Spezifikation der virtuellen Maschine gilt für „durch“. " Der vollständige Name der Klasse „So erhalten Sie den Binärbyte-Stream, der diese Klasse definiert“ gibt nicht an, dass der Binärstream aus einer lokalen Klassendatei abgerufen werden muss. Um genau zu sein, gibt er nicht an, wo und wie er abgerufen werden kann. Zum Beispiel:
Das Lesen aus einem Zip-Paket ist weit verbreitet und wird schließlich zur Grundlage für zukünftige JAR-, EAR- und WAR-Formate.
Aus dem Internet bezogen, gemeinsames Anwendungs-Applet.
Laufzeitberechnung und -generierung Die in diesem Szenario am häufigsten verwendete Technologie ist die dynamische Proxy-Technologie. In java.lang.reflect.Proxy wird ProxyGenerator.generateProxyClass zum Generieren der Binärdatei der Proxy-Klasse von $Prxoy verwendet eine bestimmte Schnittstelle.
wird aus anderen Formatdateien generiert. Dieses Szenario kommt relativ selten vor (z. B. SAP Netweaver). in die Datenbank, um die Verteilung des Programmcodes zwischen den Clustern abzuschließen.
Im Vergleich zu anderen Phasen des Klassenladevorgangs ist die Ladephase (vorbereitend gesprochen, die Aktion zum Erhalten des binären Bytestroms der Klasse in der Ladephase) die am besten kontrollierbare Phase während der Entwicklungsphase, weil die Ladephase Dies kann mit dem vom System bereitgestellten Klassenlader (ClassLoader) oder mit einem benutzerdefinierten Klassenlader erfolgen. Entwickler können die Erfassungsmethode des Bytestreams steuern, indem sie ihren eigenen Klassenlader definieren.
Nach Abschluss der Ladephase wird der binäre Bytestrom außerhalb der virtuellen Maschine im Methodenbereich gemäß dem von der virtuellen Maschine benötigten Format gespeichert. Das Datenspeicherformat im Methodenbereich wird durch die virtuelle Maschine definiert Maschinenimplementierung. Die virtuelle Maschine. Die spezifische Datenstruktur dieses Bereichs ist nicht angegeben. Anschließend wird ein Objekt der Klasse java.lang.Class im Java-Heap instanziiert. Dieses Objekt dient dem Programm als externe Schnittstelle für den Zugriff auf diese Datentypen im Methodenbereich. Teile der Ladephase und der Verknüpfungsphase (z. B. einige Aktionen zur Überprüfung des Bytecode-Dateiformats) sind verschachtelt. Die Ladephase ist noch nicht abgeschlossen und die Verknüpfungsphase hat möglicherweise begonnen, aber diese zwischen der Ladephase eingeklemmten Aktionen gehören noch dazu Die Verknüpfung der Etappeninhalte und die Startzeiten dieser beiden Etappen behalten weiterhin eine feste Reihenfolge bei.
Überprüfung:
Die Verifizierungsphase umfasst hauptsächlich vier Verifizierungsprozesse: Überprüfung des Dateiformats, Überprüfung der Metadaten, Überprüfung des Bytecodes und Überprüfung der Symbolreferenz.
1. Überprüfung des Dateiformats
Überprüfen Sie die Spezifikation des Klassendateiformats, zum Beispiel: ob die Klassendatei mit dem magischen 0xCAFEBABE beginnt, ob die Haupt- und Nebenversionsnummern innerhalb des Verarbeitungsbereichs von liegen die aktuelle virtuelle Maschine usw.
2. Metadatenüberprüfung
In dieser Phase wird eine semantische Analyse der durch den Bytecode beschriebenen Informationen durchgeführt, um sicherzustellen, dass die beschriebenen Informationen den Anforderungen der Java-Sprache entsprechen Spezifikation. Zu den Überprüfungspunkten können gehören: ob diese Klasse eine übergeordnete Klasse hat (mit Ausnahme von java.lang.Object sollten alle Klassen eine übergeordnete Klasse haben), ob diese Klasse eine Klasse erbt, die nicht vererbt werden darf (durch final geändert), und ob Die übergeordnete Klasse dieser Klasse ist eine abstrakte Klasse. Implementiert sie alle Methoden, die in der übergeordneten Klasse oder Schnittstelle implementiert werden müssen?
3. Bytecode-Überprüfung
Führen Sie eine Datenfluss- und Kontrollflussanalyse durch. In dieser Phase wird der Methodenkörper der Klasse überprüft und analysiert. Die Aufgabe dieser Phase besteht darin, sicherzustellen, dass die Methode der zu überprüfenden Klasse keine Aktionen ausführt Sicherheit der virtuellen Maschine während der Laufzeit. Stellen Sie beispielsweise sicher, dass die Typkonvertierung im Hauptteil der Zugriffsmethode gültig ist. Sie können beispielsweise ein Unterklassenobjekt einem Datentyp einer Unterklasse zuweisen. Stellen Sie sicher, dass der Sprungbefehl nicht zu Bytecode-Befehlen außerhalb des Methodenkörpers springt.
4. Überprüfung der Symbolreferenz
Ob der durch die Zeichenfolge in der Symbolreferenz beschriebene vollständig qualifizierte Name die entsprechende Klasse finden kann, die Zugänglichkeit der Klassen, Felder und Methoden in der Symbolreferenzklasse (private, protected, public, default) kann von der aktuellen Klasse aufgerufen werden.
Die Vorbereitungsphase ist die Phase, in der Speicher für Klassenvariablen formal zugewiesen und der Anfangswert der Klassenvariablen festgelegt wird im Methodenbereich „distribute“ durchgeführt werden. Es gibt zwei Wissenspunkte, die zu diesem Zeitpunkt leicht verwirrend sind. Erstens umfasst die Speicherzuweisung zu diesem Zeitpunkt nur Klassenvariablen (statisch geänderte Variablen), keine Instanzvariablen, die dem Objekt gemeinsam instanziiert werden Java-Heap. Zweitens ist der hier erwähnte Anfangswert „normalerweise“ der Nullwert des Datentyps. Angenommen, eine Klassenvariable ist definiert als:
public static int value = 12;
Dann der Variablenwert ist Der Anfangswert nach der Vorbereitungsphase ist 0 statt 12, da noch keine Java-Methode ausgeführt wurde und die putstatic-Anweisung, die 123 den Wert zuweist, nach der Kompilierung des Programms in der Klassenkonstruktormethode
Unter den oben genannten „normalen Umständen“ ist der Anfangswert Null. Im Vergleich zu einigen Sonderfällen wird der Variablenwert geändert, wenn in der Feldattributtabelle des Klassenfelds ein ConstantValue-Attribut vorhanden ist Während der Vorbereitungsphase wird der obige Klassenvariablenwert auf den durch das ConstantValue-Attribut angegebenen Wert initialisiert und wie folgt definiert:
public static final int value = 123;
Beim Kompilieren wird javac generiert das ConstantValue-Attribut für den Wert. Während der Vorbereitung legt die virtuelle Bühnenmaschine den Wert entsprechend der ConstantValue-Einstellung auf 123 fest.
In der Analysephase werden Symbolreferenzen im Konstantenpool der virtuellen Maschine durch direkte Referenzen ersetzt.
Symbolreferenz: Eine symbolische Referenz ist eine Reihe von Symbolen zur Beschreibung des referenzierten Zielobjekts. Das Symbol kann jede Form eines Literals sein, solange das Ziel bei der Verwendung eindeutig lokalisiert werden kann. Symbolische Referenzen haben nichts mit dem von der virtuellen Maschine implementierten Speicherlayout zu tun und das referenzierte Zielobjekt muss nicht unbedingt in den Speicher geladen werden.
Direkte Referenz: Eine direkte Referenz kann ein Zeiger sein, der direkt auf das Zielobjekt zeigt, ein relativer Offset oder ein Handle, der das Ziel indirekt lokalisieren kann. Direkte Referenzen beziehen sich auf die Implementierung des Speicherlayouts einer virtuellen Maschine. Die direkten Referenzen, die aus derselben Symbolreferenz auf verschiedenen virtuellen Maschineninstanzen übersetzt werden, sind im Allgemeinen nicht identisch. Wenn eine direkte Referenz vorhanden ist, muss das Referenzziel bereits im Speicher vorhanden sein.
Die Spezifikation der virtuellen Maschine legt nicht den genauen Zeitpunkt fest, zu dem die Analysephase stattfindet. Sie erfordert lediglich die Ausführung von 13 Schritten: anewarry, checkcast, getfield, instanceof, invokeinterface, invokespecial, invokestatic, invokevirtual, multianewarray, new , putfield und putstatic werden vor den Bytecode-Anweisungen zum Betreiben von Symbolreferenzen zuerst analysiert, sodass die Implementierung der virtuellen Maschine je nach Bedarf beurteilt, ob die Symbolreferenzen im Konstantenpool verarbeitet werden, wenn die Klasse geladen wird Parsen Sie den Loader oder warten Sie, bis eine Symbolreferenz verwendet werden soll, bevor Sie sie analysieren.
Die Analyseaktion wird hauptsächlich für vier Arten von Symbolreferenzen durchgeführt: Klassen oder Schnittstellen, Felder, Klassenmethoden und Schnittstellenmethoden. Entspricht den vier Konstantentypen CONSTANT_Class_Info, CONSTANT_Fieldref_Info, CONSTANT_Methodef_Info und CONSTANT_InterfaceMethoder_Info im kompilierten Konstantenpool.
1. Analyse von Klassen und Schnittstellen
3. Analyse von Klassenmethoden
>
Initialisierung:
4. Wenn JVM startet, gibt der Benutzer eine Hauptklasse an, die ausgeführt werden soll (die Klasse, die die Hauptmethode enthält), und die virtuelle Maschine initialisiert diese Klasse zuerst
In der obigen Vorbereitungsphase public static int value = 12; In Vorbereitung Nach Abschluss der Phase ist der Wert von value 0 und die Klassenkonstruktormethode
* Die Methode des Klassenkonstruktors
* Die Klassenkonstruktormethode
* Da die
*
* Statische Anweisungsblöcke können nicht in Schnittstellen verwendet werden, aber was bei Schnittstellen und Klassen nicht möglich ist, ist, dass die Ausführung der
* Die virtuelle Maschine stellt sicher, dass die
Das Obige ist der Inhalt von Java Virtual Machine Learning – Klassenlademechanismus. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn).
Verwandte Artikel:
Detaillierte Erklärung der Java Virtual Machine
Detailliertes Verständnis der Java Virtual Machine
Java Virtual Machine Learning – Zuweisung und Recycling von Objektspeicher