# Java Virtual Machine

Een Java Virtual Machine ofwel JVM is een platformonafhankelijke omgeving voor het uitvoeren van Java bytecode. Meest bekende voorbeeld hiervan is Java-code gecompileerd naar Java-bytecode, maar ook talen als Scala, Clojure en Groovy produceren code die op de JVM uitgevoerd kan worden. De JVM zorgt zelf voor geheugenbeheer, run-time optimalisatie en garbage collection. Tijdens het ontwikkelen van een applicatie hoeft de ontwikkelaar hier dus geen rekening mee te houden. Ook de verschillende mogelijke systemen waar de applicatie op zal draaien is geen zorg meer voor de ontwikkelaar, omdat er slechts één systeem is: de JVM.

## Platformonafhankelijkheid

Het platformonafhankelijke concept van Java wordt bewerkstelligd door Java broncode te vertalen (compileren) naar bytecode. Deze bytecode kan op elk willekeurig besturingssysteem waar een JVM voor beschikbaar is, worden uitgevoerd. Als gevolg hiervan wordt ieder Javaprogramma conceptueel geschreven voor maar één platform: de JVM. Dit concept is al zeer oud: in de jaren 70 bestond er het P-Codemechanisme, waarbij Pascalprogramma's naar P-code werden vertaald. Een P-code-interpreter was dan nodig om de programma's uit te voeren. Ook de oude Microsoft BASIC-interpreters vertalen hun BASIC-code eerst naar een tussentaal om de uitvoering te versnellen.

## Virtuele machine

Conceptueel is de JVM een echte computer, alleen niet uitgevoerd in hardware. De machine beschikt over opslagcapaciteit, een eigen geheugenmodel, een gespecificeerd gedrag van zijn rekeneenheid en een interne machinetaal. Ook is de basismachine conceptueel uitbreidbaar met nieuwe mogelijkheden en modules, die overeenkomen met klassen, API's en dergelijke - opgesteld in bytecode. Bekende uitbreidingen van de machine betreffen netwerkcommunicatie (java.io- en java.net-pakketten, samen conceptueel te beschouwen als een netwerkkaart voor de machine) en de API's, gericht op kleine apparaten (J2ME-uitbreidingen).

## Interpreter

Een direct gevolg van het gebruik van het Virtual Machinemodel voor het uitvoeren van computerprogramma's is dat er voor het uitvoeren van ieder programma een extra vertaalslag nodig is ten opzichte van een programma dat direct gecompileerd wordt naar de machinetaal van de onderliggende hardware. Beide modellen kennen een compilatie naar machinetaal (hardwaretaal of machinetaal voor de JVM), maar de JVM moet daarna ook zijn interne machinetaal doorvertalen naar de machinetaal van de onderliggende hardware. Dit betekent dat er altijd ergens een snelheidsverschil ligt in het uitvoeren van een programma op een JVM ten opzichte van uitvoering direct op de hardware.

## Populariteit

De JVM is echter een bijzonder populaire virtuele machine, behorend bij een populair platform dat ook stevig in opkomst is op allerlei gebieden. Dit is een drijfveer gebleken voor het ontwikkelen van allerlei technieken en trucs om het uitvoeren van programma's op een virtuele machine te versnellen. Specifiek voor de JVM geldt dat deze, sinds zijn eerste bestaan als interpreter, doorontwikkeld is tot een Just-In-Time Compiler - een machine die grote stukken code voorcompileert en voorgecompileerd opslaat in het werkgeheugen en in een cache om vertaalwerk te sparen. Daarnaast is de machine uitgerust met modules om bij programma's die langer lopen (een typisch gedrag van serverprogramma's) de vertaalde versie van het programma aan te passen aan het runtimegebruik van dat programma. Hierdoor zijn vaak optimalisaties mogelijk die in een "normaal" gecompileerd programma niet mogelijk zijn, omdat er bij het uiteindelijke gebruik geen mogelijkheid meer bestaat om in te grijpen in de manier waarop de volledige vertaling van het programma opgesteld wordt.

## Gebruik JVM voor andere talen

De JVM is van oudsher bedoeld voor het uitvoeren van programma's, opgesteld in de Javaprogrammeertaal. Omdat er veel research is geïnvesteerd in optimalisatie van snelheid, goede werking van de garbage collector is de combinatie van een virtuele machine met een grote, beproefde standaard runtime klassenbibliotheek zoals die bij een JVM hoort, zeer aantrekkelijk gebleken voor de makers van (runtimesystemen voor) andere programmeertalen. Zo zijn er compilers voor allerlei talen die naar bytecode vertalen om de platformonafhankelijkheid en/of de klassenbibliotheek van de JVM te benutten. Ook zijn er versies van interpreters voor scripttalen (zoals Scala, Ruby en Python), en systemen (zoals Macromedia Flex) die volledig geïntegreerd zijn met de JVM. Het resultaat is dat de JVM een evenbeeld is geworden van het .NET-platform wat betreft de openheid naar een veelheid aan programmeertalen.

## Architectuur van de JVM

De architectuur van de JVM is gebaseerd op een stack. Dit in tegenstelling tot architecturen gebaseerd op registers, zoals de meeste hardware. Een programma voor de JVM is een classfile en bestaat uit zogenaamde bytecodes (vandaar de naam bytecode). Iedere bytecode bevat de uit te voeren instructie en de argumenten waarop deze instructie uitgevoerd moet worden. Deze bytecode lijkt sterk op machinetaal voor een gewone computer.
Een verschil tussen de JVM en 'echte' computers is dat de JVM het niet toestaat om het geheugen direct te adresseren. In plaats daarvan werken alle instructies op de stack en op objecten.
De JVM verdeelt het geheugen dat een programma ter beschikking staat in vier delen:

### Een gedeelte voor klassen (class area).

    Hier wordt informatie opgeslagen die door alle objecten van dezelfde klasse wordt gedeeld, zoals de code (van methodes) en constanten. Vóór Java 8 heette dit de PermGen space en had zij een vaste grootte. Bij Java 8 is deze echter vervangen voor de MetaSpace. Een nieuw systeem waarbij de grootte automatisch wordt aangepast.

### Een stack

    Deze wordt gebruikt voor het opslaan van argumenten tijdens het aanroepen van methoden, het opslaan van return-waarden van methoden en van tussenresultaten van berekeningen.

### Een heap

    Hier worden alle objecten opgeslagen. Objecten die zijn vrijgegeven worden na verloop van tijd opgeruimd door de Garbage Collector.

### Een native stack

    Deze stack wordt gebruikt voor het aanroepen van native (niet in Java geïmplementeerde) functies.

## Beschikbaarheid

Een JVM is voor nagenoeg alle besturingssystemen beschikbaar, waaronder Windows, Mac OS X, Linux, Unix, OS/400 en z/OS.
* The Java(tm) Virtual Machine Specification, Second Edition, Tim Lindholm en Frank Yellin
* Java virtual machine downloaden
* Programming for the Java Virtual Machine, Joshua Engel, Addison Wesley, 1999, ISBN 0201309726
* Programming Languages for the Java Virtual Machine Een lijst van compilers en interpreters die naar de JVM toe vertalen