Java-Maschine - Dies ist der Hauptteil der Java-Plattform, mit der Sie Programme ausführen können, die in Java geschrieben sind. Es funktioniert nach dem Prinzip einer virtuellen Maschine, dh es stellt eine abstrakte Laufzeitumgebung für Programme bereit, die es demselben Programm ermöglicht, auf verschiedenen Betriebssystemen ohne Änderungen am Code ausgeführt zu werden.
Die Hauptkomponenten einer Java-Maschine sind:
- Klasse-Loader - eine Komponente, die Klassen in eine Java-Maschine lädt. Es sucht und öffnet die Bytecode-Dateien, liest sie und erstellt Klassen im Speicher. Die Loader-Klasse ist verantwortlich für das Suchen, Laden und Auflösen von Klassenabhängigkeiten.
- Bytecode-Interpreter - eine Komponente, die den Bytecode in ausführbaren Code umwandelt, der für die Maschine verständlich ist. Es analysiert den Bytecode nach den Anweisungen und führt die entsprechenden Operationen aus.
- Optimisator - eine Komponente, die ausführbaren Code optimiert und seine Leistung verbessert. Es analysiert den Bytecode des Programms und wendet verschiedene Optimierungen an, z. B. Inline-Offenlegung, Entfernung von unerreichbarem Code usw.
- Garbage Collector - eine Komponente, die Objekte entfernt, die das Programm nicht mehr benötigt. Der Garbage Collector überwacht die Speichernutzung und gibt automatisch von Objekten belegte Speicherbereiche frei, die wiederverwendet werden können.
Dank dieser Java-Architektur bietet die Maschine plattformübergreifende Leistung und eine hohe Leistung bei der Ausführung von Java-Programmen. Es ermöglicht Programmierern, sich auf die Entwicklung von Anwendungen zu konzentrieren, die unabhängig von einem bestimmten Betriebssystem sind.
Was ist eine Java-Maschine?
Das grundlegende Funktionsprinzip einer JVM besteht darin, dass sie Bytecode (Dateien .class), die das Ergebnis der Kompilierung von Java-Code sind. Der Bytecode ist eine Low-Level-Anweisung, die nur von der JVM verstanden wird. Während der Ausführung des Programms interpretiert die JVM den Bytecode, indem sie ihn in eine Reihe von Maschinenanweisungen übersetzt, die mit einem bestimmten Betriebssystem und einer bestimmten Hardwareplattform kompatibel sind.
Die Hauptkomponenten der JVM sind:
| Komponente | Die Beschreibung |
|---|---|
| ClassLoader | Lädt die Klassen zur Laufzeit des Programms und stellt sicher, dass sie aufgelöst werden. |
| Memory | Verwaltet den Speicher in der JVM, einschließlich der Aufteilung des Speichers in Stapel und Heap. |
| Execution Engine | Interpretiert den Bytecode und führt Anweisungen basierend auf der aktuellen Plattform aus. |
| Garbage Collector | Gibt automatisch den Speicher frei, der von nicht verwendeten Objekten verwendet wird. |
Die Java-Maschine bietet plattformübergreifende Funktionalität, da der Bytecode auf jeder Plattform ausgeführt werden kann, auf der die entsprechende JVM installiert ist. Dies ist besonders nützlich für Java-Entwickler, da sie Anwendungen auf einer Plattform entwickeln und ohne Änderungen am Quellcode auf einer anderen Plattform ausführen können.
Daher ist die Java-Maschine eine Schlüsselkomponente, die es ermöglicht, das Prinzip "Write once, run anywhere" (WOFA) zu implementieren - schreibe den Code einmal, führe ihn überall aus.
Arbeitsprinzip
Die Grundidee hinter der JVM ist, dass sie Java-Code in Bytecode konvertiert, der eine plattformunabhängige Programmansicht ist. Der Bytecode wird dann interpretiert oder in plattformspezifischen systemeigenen Code kompiliert.
Eine der wichtigsten Komponenten der JVM ist der Class Loader. Es lädt den Bytecode und erstellt Java-Klassen und Schnittstellen im Speicher. Der Class Loader ist auch für das Suchen und Laden von Klassenabhängigkeiten verantwortlich.
Eine weitere wichtige Komponente der JVM ist der Bytecode Verifier. Es überprüft den Bytecode auf die Einhaltung bestimmter Sicherheitsregeln, um Laufzeitfehler und Sicherheitsanfälligkeiten zu vermeiden.
Die Hauptfunktion der JVM ist die Ausführung von Bytecode. Interpretation ist eine Möglichkeit, Bytecode auszuführen. In diesem Fall führt die JVM jede Bytecodeanweisung abwechselnd aus. Die Interpretation kann jedoch relativ langsam sein. Um die Programmausführung zu beschleunigen, kann die JVM die Just-In-Time (JIT) -Kompilierung verwenden. In diesem Fall werden häufig verwendete Codeausschnitte zur effizienteren Ausführung in systemeigenen Code kompiliert.
Die JVM ist auch für die Speicherverwaltung in Java-Anwendungen verantwortlich. Es verwaltet automatisch die Speicherzuweisung und -freigabe für Objekte in Java Heap. Die JVM verwendet einen Garbage Collection-Algorithmus, um nicht verwendete Objekte zu identifizieren und zu löschen.
Alle diese Komponenten arbeiten zusammen, um eine effiziente Ausführung von Java-Anwendungen zu gewährleisten. Die JVM ermöglicht es Programmierern, Code einmal zu schreiben und ohne Änderungen auf verschiedenen Plattformen auszuführen.
Bytecode und virtuelle Maschine
Wenn der Java-Quellcode kompiliert wird, wird er in plattformunabhängigen Bytecode konvertiert. Dies bedeutet, dass das Programm nur einmal kompiliert und auf jeder Plattform ausgeführt werden kann, auf der die JVM installiert ist.
Die JVM verfügt über eine Just-In-Time (JIT) -Kompilierungseigenschaft, bei der einige Teile des Bytecode direkt zur Laufzeit des Programms in systemeigenen Code konvertiert werden. Dies verbessert die Leistung, da JIT nur die verwendeten Teile des Codes kompiliert.
Die JVM ist auch für die Speicherverwaltung während der Programmausführung verantwortlich. Mithilfe der Garbage Collection-Engine werden Objekte automatisch Speicher zugewiesen und freigegeben. Dies befreit den Programmierer von der Notwendigkeit, den Speicher manuell zu verwalten, und vereinfacht die Anwendungsentwicklung.
Eines der wichtigsten Merkmale der JVM ist die Sicherheitsprüfung zur Laufzeit des Programms. Häufig werden Webanwendungen in Java ausgeführt, die verschiedenen Arten von Angriffen ausgesetzt sein können. Die JVM stellt Mechanismen zur Typüberprüfung, Zugriffssteuerung und anderen Mechanismen bereit, mit denen sichergestellt wird, dass das Programm sicher ausgeführt wird.
Dank des Bytecodes und der virtuellen Maschine können Java-Programme auf verschiedenen Plattformen ausgeführt werden. Dies macht die Java-Sprache in der Welt der Softwareentwicklung sehr beliebt und weit verbreitet.
Hauptkomponenten
- Compiler: Konvertiert den Java-Quellcode in Bytecodes, die auf einem Java-Rechner ausgeführt werden können.
- Java Virtual Machine (JVM): Führt Bytecodes aus und steuert die Ausführung des Java-Programms.
- Class Loader: Lädt Klassen in den JVM-Speicher.
- Runtime Data Areas: Dies sind die Speicherbereiche der JVM, die zum Speichern von Daten während der Programmausführung verwendet werden, z. B. Methoden, Variablen, Aufrufstapel usw.
- Execution Engine: Führt Bytecodes aus und stellt sicher, dass das Java-Programm ausgeführt wird.
Die Arbeit eines Java-Rechners beginnt mit dem Laden von Klassen mit dem Class Loader. Die JVM verwendet dann die Execution Engine, um die Bytecodes zu interpretieren und auszuführen. Runtime Data Areas wird verwendet, um den Speicher und die Daten zu verwalten, die für die Ausführung eines Programms benötigt werden.
Klasse-Loader
Jede Loader-Klasse ist eine Instanz der Klasse ClassLoader oder seine Unterklasse. Die Loader-Klassenhierarchie bildet einen Baum, in dem jede Ebene eine separate Loader-Klasse darstellt. Der Scheitelpunkt des Baums entspricht dem System-Klassenloader, der Teil der JVM ist und Klassen aus Standardbibliotheken lädt. Andere Loader-Klassen, auch benutzerdefinierte oder benutzerdefinierte Klassen genannt, können vom Programmierer erstellt werden und Klassen aus einem Dateisystem, einem Netzwerk oder anderen Quellen laden.
Wenn eine Klasse zum Ausführen eines Programms benötigt wird, sucht die Loader-Klasse zuerst im Cache der geladenen Klassen nach ihr. Wenn die Klasse bereits zuvor geladen wurde, wird sie einfach aus dem Cache zurückgegeben. Wenn die Klasse noch nicht geladen wurde, ruft die Loader-Klasse die übergeordnete Loader-Klasse in der Hierarchie auf, damit sie versucht, sie zu laden. Wenn die übergeordnete Loader-Klasse die Klasse auch nicht finden kann, lädt die aktuelle Loader-Klasse sie selbst.
Daher bietet die Loader-Klassenhierarchie einen Mechanismus zum Suchen und Laden von Klassen nach rechts und oben in der Struktur. Wenn die Loader-Klasse die gewünschte Klasse nicht finden und laden kann, führt dies zu ClassNotFoundException. Klassenloader führen beim Laden von Klassen auch bestimmte Überprüfungen durch, z. B. eine Überprüfung auf erforderliche Abhängigkeiten oder Signaturen.
| Klasse-Loader | Die Beschreibung |
|---|---|
| Bootstrap (Bootstrap) | Lädt Klassen aus Standard-JVM-Bibliotheken. |
| Extension (Erweiterung) | Lädt Klassen aus Java-Erweiterungen, die sich im Verzeichnis "ext" befinden. |
| System (System) | Lädt Klassen aus den Anwendungspaketen und dem Pfad, der in der Umgebungsvariablen "classpath" angegeben ist. |
| Custom (benutzerdefiniert) | Lädt Klassen aus benutzerdefinierten Quellen, z. B. einem Dateisystem oder einem Netzwerk. |
Speicher und Garbage Collection
Die Java Virtual Machine (JVM) verwaltet den Speicher, der für die Ausführung eines Java-Programms reserviert ist. Begrenzte Speicherressourcen werden in verschiedene Bereiche unterteilt, z. B. Heap (Heap) und Stack (Stack).
Ein Heap ist der Speicherbereich, in dem Objekte und Arrays erstellt und gespeichert werden. Der Heap wird automatisch verwaltet, was bedeutet, dass der Programmierer sich nicht darum kümmern muss, Speicher für Objekte zuzuweisen und freizugeben. Insgesamt weist die JVM zwei Bereiche auf dem Heap zu: Young Generation (junge Generation) und Old Generation (alte Generation).
Die junge Generation ist der Speicherbereich, in dem neue Objekte erstellt werden. Es ist in zwei Generationen unterteilt: Eden Space und zwei Survivor Spaces. Objekte, die den nächsten Durchlauf des Garbage Collectors durchlaufen, werden in die Alte Generation verschoben.
Die alte Generation ist ein Speicherbereich, in dem langlebige Objekte gespeichert werden. Wenn die alte Generation voll ist, führt die JVM eine Garbage Collection durch, gibt Speicher frei und überträgt die verbleibenden Objekte.
Die Garbage Collection ist der Prozess, bei dem Speicher automatisch von Objekten freigegeben wird, die nicht mehr verwendet werden. Die JVM verfügt über einen speziellen Mechanismus namens Garbage Collector, der Objekte überwacht und bestimmt, welche entfernt werden können.
Die Garbage Collection in Java funktioniert wie folgt:
- Der Garbage Collector beginnt mit Objekten in der jüngeren Generation. Es prüft, welche Objekte nicht mehr verwendet werden, und gibt Speicher frei und verschiebt dann die verbleibenden Objekte in die alte Generation.
- Der Garbage Collector geht dann an die alte Generation über. Es gibt Speicher für Objekte frei, die nicht mehr verwendet werden, und verschiebt die verbleibenden Objekte, um freien Speicherplatz für neue Objekte zu schaffen.
- Der Garbage Collection-Prozess kann bei Bedarf aufgerufen werden, z. B. wenn der Speicher fast voll ist oder wenn die System-Methode explizit aufgerufen wird.gc().
Es ist wichtig zu beachten, dass die Garbage Collection eine teure Operation sein kann, daher wird Programmierern empfohlen, Objekte zu erstellen und Speicher effizient zu verwenden. Eine falsche Speichernutzung kann zu Speicherverlusten oder zu einer Beeinträchtigung der Programmleistung führen.