**Java virtuaalmasin** (inglise keeles *Java Virtual Machine*) on abstraktne masin, mis interpreteerib kompileeritud Java baitkoodi arvuti protsessorile arusaadavateks instruktsioonideks. Java virtuaalmasina puhul on tegemist abstraktsioonikihiga, mis võimaldab jooksutada Java baitkoodiks kompileeritud rakendusi riistvaraplatvormist sõltumata. Masin tagab, et baitkood valideeritakse ning täidetakse korrektselt.

Levinuim Java virtuaalmasina implementatsioon on Oracle poolt hallatav HotSpot.

Spetsifikatsioon
----------------

Iga Java virtuaalmasina implementatsioon peab järgima Java virtuaalmasina spetsifikatsioone. Java virtuaalmasina spetsifikatsioon määratleb üldised nõuded virtuaalmasina implementatsioonidele, et tagada kõikide Java virtuaalmasinate toimimine standardiseeritud moel. Iga Java baitkoodiks kompileeritud rakendus peab olema võimeline jooksma sellises masinas, mis Java virtuaalmasina spetsifikatsioone implementeerib.

### Arhitektuur

#### Tüübid

Java virtuaalmasinas on kaks erinevat tüüpi: primitiivsed tüübid ning viitetüübid (*reference types*). 
Spetsifikatsioon defineerib 9 primitiivset tüüpi:

1. Numbrilised tüübid
	* Täisarvulised tüübid: `byte`, `short`, `int`, `long`, `char`
	* Ujuvkomaarv tüübid: `float`, `double`
2. Tõeväärtustüüp `boolean`
3. `returnAddresss` – tüüp, mis hoiab viiteid Java virtuaalmasina instruktsioonide operatsioonikoodidele (*opcodes*) ja on ainuke primitiivne tüüp, millel pole Java programmeerimiskeeles ühest vastet.

Viitetüübid jagunevad kolmeks: klassitüübid, massiivitüübid ja liidesetüübid (*interface types*). Nende tüüpide väärtused vastavad dünaamiliselt loodud klassi, massiivi või liidese tüübi instantsidele.

#### Mälukasutus

Java virtuaalmasin defineerib mitmeid mälustruktuure, mis on tarvilikud masina tööks. Mõningad struktuurid on globaalsed virtuaalmasina kontekstis ning mõned struktuurid on eraldi iga lõime jaoks. Java virtuaalmasin kasutab enda töös nii registreid kui ka pinusid.

1. `pc` register
	* Igal lõimel on oma `pc` (*program counter*) register, mis viitab lõime poolt hetkel jooksutatavale instruktsioonile.
2. Virtuaalmasina pinud
	* Igal lõimel on oma privaatne pinu, mis initsialiseeritakse lõime loomisel.
	* Pinus hoitakse kohalikke muutujaid ning hallatakse meetodite väljakutsete ahelat.
3. Kuhi (*heap*)
	* Kuhi on kõikide lõimede jaoks ühine ning selles alas hoitakse klasside instantse ning massiive. Kuhi luuakse Java virtuaalmasina loomise hetkel.
	* Kuhja mälukasutust haldab automaatne prügikoristuse (*garbage collection*) süsteem.
4. Meetodite tsoon (*Method area*)
	* Ala on kõikidel lõimedel ühine ning luuakse Java virtuaalmasina loomise hetkel.
	* Siin hoitakse kompileeritud programmikoodi ning klassidega seonduvat infot nende meetodite ning väljade kohta.
5. Omameetodite pinu (*Native method stack*)
	* Java virtuaalmasin võimaldab välja kutsuda meetodeid, mis ei ole Java programmeerimiskeeles kirjutatud. Selliste meetodite väljakutsed hoitakse lõime privaatsest pinust eraldi.
	* Pinu luuakse lõime loomise hetkel.

### Klasside laadimine

Java virtuaalmasina spetsifikatsioon kirjeldab detailselt Java klassifailide formaadi ning nende laadimise funktsionaalsust. Klassilaadija (*class loader*) peab olema suuteline tuvastama ja laadima korrektseid Java klassifaile. Klassilaadija toimib klassi laadimisel järgmisi samme jälgides:

1. Laadimine: klassilaadija leiab ja laeb vastava klassi tüübi baidid
2. Linkimine: toimub verifitseerimine, ettevalmistamine ning viidete lahendamine
	* Verifitseerimine: klassi tüübi korrektsuse tagamine
	* Ettevalmistamine: klassi muutujate jaoks mälu reserveerimine
	* Viidete lahendamine: teatud virtuaalmasina instruktsioonid võivad kasutada sümboolseid viiteid (*symbolic reference*) klassi tüübi viidete tabelis (*constant pool*) esinevatele väärtusele. Selle sammu käigus lahendatakse need viited, et kätte saada viidetele vastavad objektid.
3. Initsialiseerimine: Java koodi väljakutsumine, mis omistab klassi muutujatele vastavad algväärtused

### JIT kompilaator

Tavaline virtuaalmasina töökäik näeb ette, et masin interpreteerib sisendiks antud Java baitkoodi instruktsioone, mis on aeglasem, kui platvormispetsiifilise masinkoodi jooksutamine.
Selle probleemi lahendamiseks rakendab Java virtuaalmasin JIT (*just in time*) kompileerimismeetodit. JIT kompilaator võimaldab programmi käitamisajal teatud programmilõike teisendada masinkoodiks, et seeläbi tagada nende osade kiirem täitmine. Sellist kompleerimise meetodit rakendatakse programmi osade peal, mida kõige tihedamini jooksutatakse. JIT kompilaatori olemasolu parandab oluliselt Java virtuaalmasinas jooksvate rakenduste jõudlust.

Viited
------

1. ↑  "Java SE HotSpot at a Glance". Vaadatud 15. märts 2018. .
2. 1 2 3 4 5  Lindholm, Tim, Frank Yellin, Gilad Bracha, ja Alex Buckley. "The Java® Virtual Machine Specification", 2017, 618.