DieJava Virtual Machine (abgekürztJava VM oderJVM) ist der Teil derJava-Laufzeitumgebung (Java Runtime Environment, JRE) fürJava-Programme, der für die Ausführung desJava-Bytecodes verantwortlich ist. Hierbei wird im Normalfall jedes gestartete Java-Programm in seiner eigenenvirtuellen Maschine (VM) ausgeführt. Der andere Teil der Java-Laufzeitumgebung sind die Java-Klassenbibliotheken.
VomJava-Compiler erzeugter (plattformunabhängiger)Bytecode wird von einer plattformabhängigen Java Virtual Machine ausgeführt. Die erzeugten Bytecode-Dateien (Dateiendung „.class“) werden während derLaufzeit in die lokaleMaschinensprache übersetzt. Die virtuelle Maschine arbeitet dabei wie einInterpreter, ist jedoch wesentlich schneller, da z. B. keineSyntaxüberprüfungen mehr vorgenommen werden müssen.
Die Java Virtual Machine bietet neben der Plattformunabhängigkeit des Bytecodes auch einen Gewinn an Sicherheit. Sie überwacht zur Laufzeit die Ausführung des Programms, verhindert also zum BeispielPufferüberläufe, welche zu unvorhersehbarem Verhalten wie etwa dem Absturz des Programmes führen. Im speziellen Fall von Java fällt diese Überwachung sehr einfach aus, da Java nicht direktZeiger unterstützt (nur implizit).
Um die Ausführungsgeschwindigkeit von Java-Programmen zu erhöhen, setzen die meisten Java-VMs sogenannteJIT-Compiler (JITC) ein, die unmittelbar während des Programmablaufs den Bytecode „JustInTime“ dauerhaft inMaschinencode übersetzen.Eine Weiterentwicklung dieses Ansatzes ist der Hotspot-Optimizer vonSun, welcher mit dynamischer Optimierung arbeitet:
Oft ist zum Zeitpunkt derKompilierung nicht bekannt, welche konkreteEingabe eineSoftware verarbeiten muss. Demzufolge muss die Software mit allen Arten von Eingaben zurechtkommen. Die Eingabe wird demnach inVariablen gespeichert. Nach dem Start des Programms werden jedoch viele Variablen nicht mehr geändert. Folglich sind diese – von einem Zeitpunkt kurz nach dem Start an – Konstanten. Wird nun erst nach diesem Zeitpunkt die Software für die System-Architektur kompiliert (dies ist beiHotSpot der Fall), so können diese Konstanten berücksichtigt werden. BestimmteVerzweigungen, die nur von solchen „Halbkonstanten“ abhängig sind, sind dann für immer eindeutig und stellen somit kein Risiko für eine falscheSprungvorhersage dar. Ein solcher Programmcode kann also schneller ablaufen als zu einem früheren Zeitpunkt kompilierter Code.
Ausführungen inHardware sind dieJava-Prozessoren,Mikroprozessoren, die Java-Bytecode alsMaschinensprache verwenden. Sie konnten sich gegen die schnelle Steigerung der Leistungsfähigkeit von prozessorspezifischen JVMs auf anderssprachigen Prozessoren, wie in PCs und Mobiltelefonen eingesetzt, nicht durchsetzen.
Die Java VM schottet die in ihr laufenden Prozesse vom Betriebssystem ab (Green Threads). Sie bildet standardmäßig Java-Threads durch Threads des Betriebssystems ab. Nur in Ausnahmefällen erfolgt das Thread-Management durch die Java VM. Somit ist es auch möglich, auf einem Betriebssystem, das kein Multithreading unterstützt, eine Java VM mit vollem Funktionsumfang anzubieten.
Die Java VM hat stets volle und standardkonforme Hoheit über die Java-Threads, d. h. der Programmierer braucht nicht die betriebssystemspezifischen Multi-Threading/Tasking/Processing-Eigenschaften zu berücksichtigen und kann sich stets auf dieJRE verlassen. Nachteil ist, dass Probleme, die von einem Thread ausgehen, seitens des Betriebssystems dem gesamten Prozess zugeordnet werden. Gängige Betriebssysteme (wie zum Beispiel Linux, Windows) erlauben Kontrolle über diese „nativen“ Threads allenfalls über Software von Drittanbietern, wie beispielsweise die mit demJDK mitgelieferte VisualVM. Standardwerkzeuge wie beispielsweise derWindows Taskmanager zeigen Systemthreads jedoch nicht an.
Neben Java gibt es auch andere Sprachen, die als Programmiersprachen für JVM-Programme benutzt werden können. Unter anderem folgende Sprachen können auf einer JVM laufen:
Concurnas, eine Multi-Paradigma-Programmiersprache fürnebenläufige,verteilte undreaktive Anwendungen, mit Python-ähnlicher Syntax, Unterstützung für GPU-Computing und Off-Heap-Speicherverwaltung.[1][2]
Nice, ergänzt Java mit parametrischen Typen, anonymen Funktionen, Multimethoden, Tupel und optionalen Parametern[4]
Scala, eine Sprache, die Eigenschaften von Java mit funktionaler Programmierung vereint.
Daneben gibt es eine Reihe vonSkripting-Sprachen, die von Java aus aufrufbar sind. Dazu gehörtJavaScript (mittlerweile standardisiert als ECMAScript) mit dem „Rhino“-Interpreter (ein Mozilla-Projekt) bis Version 7 bzw. mit dem „Nashorn“-Interpreter ab Version 8. AuchJavaFX enthielt in den Versionen 1.x eine Skripting-Sprache vor allem für grafische Elemente, ist aber ab Version 2.0 in pure Java implementiert.
Mit der kontinuierlichen Verbesserung der JavaScript-Ausführungsgeschwindigkeit, kombiniert mit der verstärkten Nutzung mobiler Geräte, deren Webbrowser keine Unterstützung für Plugins bereitstellen, gibt es Bemühungen, diese Benutzer durch Kompilierung in JavaScript anzusprechen. Es ist möglich, den Quellcode oder JVM-Bytecode nach JavaScript zu kompilieren.
Die Kompilierung des JVM-Bytecodes, der für alle JVM-Sprachen universell ist, ermöglicht es, auf dem bestehenden Compiler der Sprache aufzubauen und Bytecode zu erstellen. Die wichtigsten JVM-Bytecodes für JavaScript-Compiler sind TeaVM[5], der Compiler im Dragome Web SDK[6], Bck2Brwsr[7], und j2js-Compiler[8].