Een virtuele machine is een computerprogramma dat een computer nabootst, waar andere programma's op kunnen worden uitgevoerd.

Deze techniek wordt gebruikt om de overdraagbaarheid van programmatuur te verbeteren, en ook om het gelijktijdig gebruik van de computer door verschillende gebruikers robuuster te maken.

Virtuele machines zijn er in twee varianten: programmeertaal-specifiek of als emulator.

Programmeertaal-specifiek 
Een virtuele machine voor een programmeertaal biedt een abstractielaag voor de werkelijke computer: een verzameling basisfuncties waar programma's in de programmeertaal gebruik van moeten maken om de functies van de computer aan te spreken. Dit is precies wat een besturingssysteem doet, en een dergelijke machine fungeert dus als besturingssysteem voor in die taal geschreven programma's; de reden dat van een virtuele machine wordt gesproken is dat de virtuele machine zelf vaak een programma is dat wordt uitgevoerd op een bestaand besturingssysteem.

De virtuele machine is de verbindende laag tussen de uitgevoerde code en de computerhardware (zoals de microprocessor) waarop het uiteindelijke programma wordt uitgevoerd, eventueel via een ander besturingssysteem. De op een virtuele machine uitgevoerde code spreekt niet direct de 'echte' hardware aan, maar gebruikt alleen de functies die worden aangeboden door de virtuele machine.

Wanneer voor een bepaald platform (hardware en eventueel besturingssysteem) een virtuele machine gemaakt is, kan elk programma dat voor deze virtuele machine geschreven is, worden uitgevoerd. De implementatie van een virtuele machine kan in elke andere programmeertaal gebeuren. Op deze manier wordt platform-onafhankelijkheid bereikt: programma's kunnen worden uitgevoerd op elk systeem waarvoor de virtuele machine is geïmplementeerd. Overdraagbaarheid wordt een kwestie van het implementeren van een virtuele machine, in plaats van een probleem dat voor elk programma afzonderlijk moet worden opgelost.

Een voorbeeld van een programmeertaal-specifieke virtuele machine is de Java Virtual Machine (JVM). Het resultaat van de compilatie van een Javaprogramma wordt bytecode genoemd. Een JVM kan dan deze bytecode-instructies een voor een interpreteren door ze te vertalen naar één of meerdere echte machine-instructies. Ook zijn er JVM's die de bytecode just in time (JIT) compileren naar de instructies van het platform. Dit levert uiteraard prestatiewinst op in vergelijking met interpretatie.

Het idee van bytecode is niet recent. Sommige varianten van de programmeertaal Pascal hadden dit concept reeds; hier heette dit p-code of pseudocode. Ook veel Prolog implementaties zijn op een virtuele machine gebaseerd: de Warren Abstract Machine.

Emulatie 
Een virtuele machine die de hardware van de computer emuleert, is niet gericht op een programmeertaal (zoals Java of Pascal), maar emuleert een fysieke computer (dat wil zeggen de processor en andere hardware), zodanig dat een bestaand besturingssysteem op deze emulatie kan draaien, alsof het een fysieke computer betreft. Met een dergelijke virtuele machine is het dus bijvoorbeeld mogelijk om Windows te emuleren in een GNU/Linux-omgeving, of omgekeerd.

Virtualisatie, sinds de jaren 60 op bepaalde soorten mainframes algemeen gebruikelijk, wordt tegenwoordig ook op PCs veel toegepast.

Programmeerconcept
 
Machine