Was JVM laden muss, ist ein binärer Stream, der in Form einer .class -Datei oder anderer Formulare sein kann. Wenn Sie es gemäß den Ladestandards entwerfen, wird es kein großes Problem geben.
Im Folgenden analysiert hauptsächlich die beiden Fragen des Mechanismus und der Standards:
Nehmen wir zunächst den Lademechanismus von Java -Klassendateien, der dem Lademechanismus von Variablen ähnelt. Es wird zuerst die Klassendatei in den Speicher geladen, dann die Daten überprüft, analysiert und initialisiert und schließlich einen Java -Typ bildet, den die virtuelle Maschine direkt verwenden kann. Da Java den JIT -Mechanismus übernimmt, wird er nur langsam geladen, aber seine Vorteile sind offensichtlich, es hat eine hohe Flexibilität und unterstützt dynamische Belastungen und dynamische Verbindungen.
Lassen Sie uns als nächstes über den Ladungsprozess der Klasse sprechen:
Der grundlegende Prozess einer Klassenbelastung liegt in der folgenden Reihenfolge, einige sind jedoch nicht ausschließlich in dieser Reihenfolge und einige befinden sich in der ungeordneten Reihenfolge. Beispielsweise erfordert die dynamische Belastung eine Initialisierung und dann an Parsen.
1. Laden
Es liegt an der virtuellen Maschine zu entscheiden, aber es gibt auch Fälle, in denen die obige Phase ausgeführt wird, da die folgende Phase ausgeführt werden soll.
Zu diesem Zeitpunkt macht die virtuelle Maschine drei Dinge:
Lesen Sie zunächst den binären Stream der Datei über einen voll qualifizierten Namen.
Zweitens legen Sie die statischen Methoden und Variablen in die Datei in den Methodenbereich.
Drittens erzeugen Sie ein Objekt und legen Sie es als Zugriffsportal in den Haufen.
Beachten Sie, dass der erste darin besteht, den binären Stream zu lesen, und es heißt nicht, aus welcher Datei sie gelesen wird oder woher er gelesen wird. Daher schafft es eine starke Skalierbarkeit in Java, die aus Glas, Reißverschluss oder aus der Netzwerkschicht, der Datenbankschicht usw. stammen kann.
Hauptsächlich die Deklaration des Objekt- und Methodenbereichs.
2. Überprüfung
Stellen Sie sicher, dass der binäre Fluss den Anforderungen der virtuellen Maschine entspricht und nicht den VerifyError entspricht.
Erstens, Überprüfung des Dateiformates, ob es magische Zahlen gibt und ob sie die Anforderungen von Java -Dateien erfüllen;
Zweitens die Metadatenüberprüfung, ob sie den Java -Codespezifikationen entspricht, z. Drittens analysiert die Bytecode-Überprüfung den Datenfluss und den Steuerfluss und stellt sicher, dass es kein Verhalten gibt, das die virtuelle Maschine schädelt, z.
Viertens, symbolische Referenzüberprüfung, hauptsächlich, ob die Beschreibung von Klassen, Variablen und Methoden gefunden werden kann, z.
Bestimmen Sie hauptsächlich die interne Struktur
3.. Vorbereiten
Das Zuweisen eines Anfangswerts einer Klassenvariablen ist normalerweise ein 0 -Wert wie eine statische Variable, ohne einer Instanzvariablen einen Wert zuzuweisen.
4. Analyse
Der Prozess der Umwandlung symbolischer Referenzen in einem konstanten Pool in direkte Referenzen. Die hier erwähnte symbolische Referenz bezieht sich auf den variablen Typ, und direkte Referenz bezieht sich auf den Griff, der direkt an das Objekt lokalisiert werden kann. Klasse, Methode, Feld, Schnittstellenanalyse, das relevante Objekt gemäß dem voll qualifizierten Namen erhalten und seinen Typ erhalten. Wenn es keinen Zugriff auf die Klasse gibt, wird Illegalacceserror geworfen, kein Feld NoSuchfielderror wird geworfen, keine Methode, die NoSuchmethoderror geworfen wird, wenn es sich um eine Klasse handelt oder nicht, wird die Schnittstelle geworfen.
5. Initialisierung
Laden Sie Klassen und erforderliche Ressourcen gemäß den Programmanforderungen. Es gibt nur vier Situationen, und Sie müssen aktiv initialisieren, bevor Sie die nächste Operation ausführen können, sodass Sie zuerst die oben genannten vier Schritte ausführen müssen.
Erstens erzeugt Klassen mit neuen oder statischen Schlüsselwörtern, Neuen Objekte und statische statische Lasten, diese beiden werden offensichtlich initialisiert.
Zweitens, wenn Sie eine Klasse verwenden, können Sie nichts dagegen tun.
Drittens müssen die Methoden in der Reflexionsklasse initialisiert werden, oder?
Viertens die Hauptausführungsklasse, die Klasse, die die Hauptmethode verwendet. Andere passive Initialisierungssituationen müssen nicht berücksichtigt werden.
Kleine Beispiele:
public class SuperClass {static {System.out.println("SuperClass!!");}public static int value = 1;}public class SubClass extends SuperClass {static {System.out.println("SubClass!!");}}public class TestClassLoad {public static void main(String[] args) {System.out.println (subclass.Value); SuperClass SuperClass = new subclass ();}} SuperClass !! 1SubClass !!Das Ausführungsergebnis zeigt ein Problem: Wenn die Unterklasse die übergeordnete Klassenvariable aufruft, wird die Unterklasse nicht initialisiert, da die Code -Beziehung zu diesem Zeitpunkt nichts mit der Unterklasse zu tun hat. Wenn die Unterklasse initialisiert wird, wird die übergeordnete Klasse nicht erneut initialisiert, da die übergeordnete Klasse in der aktuellen Methodekörper initialisiert wurde. Der einzige Unterschied zwischen einer Schnittstelle und einer übergeordneten Klasse besteht darin, dass die Schnittstelleninitialisierung nicht die übergeordnete Schnittstelle erfordert und nur dann initialisiert wird, wenn die übergeordnete Schnittstelle verwendet wird und derselbe Klassenkonstruktor generiert wird.
Zu diesem Zeitpunkt wird der Klassenkonstruktor geladen und alle Variablen in der Klasse werden initialisiert. Natürlich wird die Elternklasse vor der Kinderklasse initialisiert.
6. Verwendung
Nach dem Laden, wie man es nennt, Zeichnen, Berechnung usw.
7. Deinstallieren
Die Klasse wird nicht mehr genannt
Ob die beiden Klassen gleichermaßen gleich sind
Warum die oben genannten Fragen stellen? Als nächstes werden wir über einen Lademechanismus einer virtuellen Maschine sprechen.
Aus der Sicht von Java -Virtual -Maschinen gibt es zwei Klassenlader, einer wird als Systemlader (Bootstrap Classloader) bezeichnet und der andere als benutzerdefinierte Loader (Extends Classloader) bezeichnet. Dies wird in zwei unterteilt, einer wird als Anwendungslader bezeichnet und der andere als Erweiterungsklassenlader bezeichnet, der im Allgemeinen an erstere standardmäßig wird. und unsere Anwendungsbelastung erfolgt hauptsächlich von den oben genannten drei Ladern. Die Beziehung zwischen den drei ist Anwendung> Erweiterung> Bootsrap. Der übergeordnete Delegationsmechanismus bezieht sich auf die Kombination von zwei Paaren. Der untergeordnete Loader ruft zunächst die übergeordnete Loader -Methode auf, und das Zielobjekt wird nicht vor der Verwendung des untergeordneten Laders gefunden.
Der Pseudo-Code lautet wie folgt:
LoadClass (String -Name, boolean Resolve) {Klasse c = findloadedClass () if (c == null) {if (parent! = null) c = übergeordnet.loadClass (Name, Falsch);Java befürwortet, dass wir die Logik unserer Anrufklasse in FindClass schreiben, die uns hilft, den übergeordneten Delegationsmechanismus normal zu verwenden.
Zerstöre 1. Schreiben Sie die Lastklasse neu
Zerstören Sie 2. Verwenden Sie den Thread Context Loader, um den Elternloader die untergeordnete Ladermethode aufzurufen
Zerstörung 3. Die häufig verwendete Methode für das heiße Laden besteht darin, den Klassenlader anzupassen und das ursprüngliche Fehlermodul - OSGI zu überschreiben
Wenn die Regeln zwischen benutzerdefinierten Ladern jedoch verwirrt sind und es das Problem gibt, dass gleichzeitig sich aufeinander bezieht, wird die Klasse schließlich nicht gefunden, und die Deadlock- und Speicher -Lecks von Threads treten auf.
In Bezug auf die heiße Reparatur, auch als Plug-Ins bezeichnet, sind die beliebtesten Hotfix, Nuwa, Droidfix und Fix usw. Diese Frameworks finden Sie auf Github oder anderswo. Die Prinzipien sind wie oben, die Methoden sind vielfältig, es gibt Abdeckung, Umleitung usw. durch Konfiguration, Setzen von Aktionen usw.; Als Plug-In müssen die folgenden Bedingungen erfüllt sein:
1. kann unabhängig installiert werden, kann aber nicht unabhängig ausgeführt werden
2. Sei rückständiger Kompatibilität, kann erweitert werden
3. Es kann nur im Host -Programm ausgeführt und kann deaktiviert oder ersetzt werden
Die obige Beispielerläuterung des Lademechanismus für Java Advanced Virtual Machine ist der gesamte Inhalt, den ich mit Ihnen teile. Ich hoffe, Sie können Ihnen eine Referenz geben und ich hoffe, Sie können wulin.com mehr unterstützen.