
Als virtuelle Maschine (VM) wird in der Informatik die Software-technische Kapselung eines Rechnersystems innerhalb eines lauffähigen Rechnersystems bezeichnet. Die virtuelle Maschine bildet die Rechnerarchitektur eines real in Hardware existierenden oder eines hypothetischen Rechners nach. Es werden zwei Arten virtueller Maschinen unterschieden.
Systembasierte virtuelle Maschinen bilden einen realen Rechner so vollständig nach, dass Betriebssysteme, die für ihn entworfen wurden, sich auf der virtuellen Maschine genauso wie auf dem entsprechenden realen Rechner ausführen lassen. Beispiele für bekannte Produkte oder Komponenten, die systembasierte virtuelle Maschinen realisieren, sind VMware Workstation sowie vSphere von VMware bzw. Broadcom, VirtualBox von Oracle, Parallels Desktop for Mac von Parallels, Xen von Citrix, Hyper-V in Windows und KVM in Linux.
Prozessbasierte virtuelle Maschinen erlauben lediglich, einzelne Programme abstrahiert von der Ausführungsumgebung einer realen Rechnerarchitektur auszuführen, indem sie eine darauf aufbauende Laufzeitumgebung bereitstellen. Meist werden solche virtuellen Maschinen für mehrere reale Rechnerarchitekturen bereitgestellt, so dass die Anwendung nur einmal compiliert werden muss, wodurch Bytecode für eine hypothetische Rechnerarchitektur entsteht, der dann durch den Interpreter oder Just-in-time-Compiler der unterschiedlichen virtuellen Maschinen auf allen realen Plattformen ohne Änderung ausgeführt werden kann. Bekannte Beispiele solcher Umgebungen mit entsprechenden virtuellen Maschinen sind die Java-Laufzeitumgebung als Teil der Java-Plattform und die Common Language Runtime (CRL) als Teil des .NET Frameworks.
Der zugrunde liegende Ansatz wird auch als vollständige Virtualisierung bezeichnet. Er basiert im Wesentlichen auf der von Robert Goldberg gegebenen und von Gerald Popek 1972 noch enger gefassten Definition:
„Eine virtuelle Maschine ist ein effizientes, identisches und isoliertes Duplikat eines echten Prozessors.“
Zur Unterscheidung zwischen realen Rechnern und der auf ihnen ausgeführten virtuellen Maschinen werden diese einerseits Gastgeber, Wirt oder Host und andererseits Gast genannt.
Systembasierte virtuelle Maschinen werden direkt auf der CPU des Gastgebers ausgeführt und nutzen üblicherweise deren Virtualisierungsfunktionen, beispielsweise die der x86-Prozessoren. Dagegen wird bei Emulatoren die Ausführung rein als Software realisiert, wodurch auch eine andere Rechnerarchitektur als die des Gastgebers nachgebildet werden kann.
Die abstrahierende Schicht zwischen realem oder Host- bzw. Wirt-Rechner, auf dem die virtuelle Maschine ausgeführt wird, und der virtuellen Maschine wird Hypervisor oder Virtual Machine Monitor genannt. Sie erlaubt in der Regel den gleichzeitigen Betrieb mehrerer virtueller Maschinen auf einem physischen Rechner, übernimmt die Erstellung und Verwaltung der virtuellen Maschinen und verteilt im Betrieb die Hardware-Ressourcen derart, dass für jedes einzelne Gastbetriebssystem alle Ressourcen bei Bedarf verfügbar sind, so, als ob nur ein Betriebssystem vorhanden wäre.
In seiner Doktorarbeit „Architectural Principles for Virtual Computer Systems“ von 1973 unterscheidet R. Goldberg zwei Typen von Hypervisoren:
Einige Virtualisierungen (z. B. KVM und Hyper-V) nutzen hybride Hypervisoren, die Funktionen von Typ-1- und Typ-2-Hypervisoren kombinieren.
Aus IBMs Anstrengungen, ein robusteres Time-Sharing auf seinen Großrechnern zu ermöglichen, resultierte der erste Hypervisor. Die 1964 gegründete Projektgruppe entwickelte dafür CP-40/CMS, das aus dem Hypervisor Control Program (CP) sowie dem Einzelbenutzerbetriebssystem Cambridge Monitor System (CMS) für die virtuellen Maschinen bestand und auf ein durch zusätzliche Hardware zur Übersetzung von Speicheradressen modifiziertes System/360 Model 40 lief. Dieser Rechner und das ab 1967 produktiv im Forschungsbetrieb eingesetzte System/360 Model 67 mit CP-67/CMS unterstützten so erstmalig die vollständige Virtualisierung und erlaubten mehreren Benutzern gleichzeitig auf einem physischen Rechner jeweils ein eigenes Einzelbenutzerbetriebssystem in einer virtuellen Maschine unabhängig zu nutzen.
Ursprünglich musste die CPU sowie weitere Hardware und Schnittstellen eines Rechners nur ein laufendes Betriebssystem unterstützen. Dafür reichen zwei Privilegienstufen aus: der Kernelmodus, in dem das Betriebssystem, meistens sogar nur der Kernel, die CPU privilegiert (alle Befehle verfügbar) nutzt, und der Benutzermodus, in dem die übrigen Prozesse u. a. der Anwendungssoftware die CPU eingeschränkt (reduzierter Befehlssatz) nutzen.
Zusätzliche Betriebssysteme in virtuellen Maschinen „nehmen an“, dass sie das einzige Betriebssystem auf dem Rechner sind und die CPU im Kernelmodus nutzen können. Tatsächlich ist dies nicht der Fall und der im Kernelmodus laufende Hypervisor muss alle aus Sicht der Gastbetriebssysteme privilegierten Befehle in „echte“ privilegierte Befehle übersetzen. Notwendig ist auch die Nachbildung und Erweiterung der virtuellen Speicherverwaltung im Hypervisor zur Vermeidung von Konflikten bei Speicherzugriffen der Gastbetriebssysteme. Eine Alternative zu diesen beiden Maßnahmen ist die später erläuterte Paravirtualisierung.
Der Hypervisor wird entlastet und die Virtualisierung performanter, wenn die CPU durch Erweiterungen der Privilegienstufen, des Befehlssatzes und der MMU (Second Level Address Translation) Befehle, die vom Hypervisor oder den Gastbetriebssystemen kommen, erkennen und verarbeiten kann.
In ihrem Artikel Formal Requirements for Virtualizable Third Generation Architectures von 1974 legen Gerald J. Popek and Robert P. Goldberg die formalen Grundlagen und stellen die grundlegenden Anforderungen an eine Architektur dar, um virtuelle Maschinen mit Hilfe eines Hypervisors zu unterstützen.
Während Motorola bereits 1983 mit Motorola 68010 den ersten Virtualisierung unterstützenden Prozessor u. a. für Heimcomputer, PCs und Workstations auf den Markt brachte (weite Verbreitung erlangte aber erst ein Jahr später die Motorola-68020-CPU), dauerte es noch 22 Jahre bis Intel mit den Prozessoren Pentium 4 „Prescott“ 662 und 672 sowie Xeon „Paxville“ und der in ihnen integrierten Virtualisierung VT-x (zunächst Vanderpool genannt) nachzog. AMD folgte 2006 mit der zu VT-x inkompatiblen Virtualisierungstechnik AMD-V (anfangs „Pacifica“ und anschließend „AMD Secure Virtual Machine“ genannt) für die damals aktuellen Revisionen des AMD Opteron (Revision F, vierstellige Serien 1000, 2000 und 8000), AMD Athlon 64 FX-62 und Athlon 64 X2 (Windsor-Kerne, Serien 4000+ bis 5200+) sowie AMD Turion 64 X2. Zwei Jahre später brachte VIA die CPU VIA Nano, bei der ab Stepping 3 das zu VT-x kompatible VIA VT aktiviert war.
Systembasierte virtuelle Maschinen werden u. a. in folgenden Anwendungsszenarien eingesetzt:
Der Einsatz systembasierter virtueller Maschinen bietet gegenüber der direkten Ausführung von Betriebssystemen auf dem Rechner einige Vorteile:
Allerdings „erkauft“ man sich diese Vorteile auch mit einigen Nachteilen, die sich gegenüber direkter Ausführung des Betriebssystems auf dem Rechner ergeben:
Prozessbasierte virtuelle Maschinen werden u. a. in folgenden Anwendungsszenarien eingesetzt:
Der Einsatz von prozessbasierten virtuellen Maschinen bietet folgende Vorteile:
Der Einsatz von prozessbasierten virtuellen Maschinen hat folgende Nachteile:
Diese Nachteile können durch geeignete (z. B. dynamische) Optimierung verringert werden. Eine weitere Möglichkeit ist die automatische Kompilierung mittels Ahead-of-time-Compiler unmittelbar vor der Ausführung. Damit wird das Backend eines hochoptimierenden, maschinenorientierten Compilers unmittelbar auf dem Anwendersystem ausgeführt. Dadurch kann der Compiler noch spezifischere Optimierungen für das System des Anwenders vornehmen als es bei einem vorkompilierten Programm ohne spezielle Optimierungen für das System bzw. den Prozessor des Anwenders möglich wäre.
Die Geschichte der prozessbasierten virtuellen Maschinen begann mit dem bahnbrechenden Aufsatz Transportability of Software Applications on Microcomputers von W. Wellbourne (1983) und der vorausgegangenen Arbeit A Comparison of Pascal Intermediate Languages von P. Nelson (1979). Es geht hier um die Lösung des Problems, Anwendungscode, der für eine Rechnerarchitektur entwickelt wurde, ohne Änderungen auf einer anderen Rechnerarchitektur auszuführen. Insbesondere um den Portierungsaufwand für Anwendungen von einer Architektur zu anderen (z. B. neuen Rechnerarchitekturen) gering zu halten.