Macchina virtuale Java: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
m +wl, fix Bibliografia
non serve specificare l'ambito
 
(17 versioni intermedie di 9 utenti non mostrate)
Riga 1:
[[File:Java_Logo.svg|thumb|upright=0.5|Logo di [[Java (linguaggio di programmazione)|Java]], il primo [[linguaggio di programmazione ad alto livello]] per la JVM]]
{{vedi anche|Architettura della macchina virtuale Java}}
In [[informatica]] la '''macchina virtuale Java''' (detta anche '''Java Virtual Machine''' o '''JVM''') è il componente [[software]] della [[piattaforma Java]] che [[esecuzione (informatica)|esegue]] i [[programma (informatica)|programmi]] tradotti in [[bytecode]] dopo la prima fase di [[compilatore|compilazione]] in bytecode (tra i [[linguaggi di programmazione]] che possono essere tradotti in bytecode troviamo [[Java (linguaggio di programmazione)|Java]], [[Groovy]], [[Clojure]], [[Scala (linguaggio di programmazione)|Scala]] ed [http://eta-lang.org/ Eta]).
 
La '''macchina virtuale Java''' (detta anche '''Java Virtual Machine''' o '''JVM''') è il componente della [[piattaforma Java]] responsabile per l'esecuzione dei [[programma (informatica)|programmi]] in formato [[bytecode]].
== Principio ==
I passi che devono essere fatti per eseguire un programma scritto in linguaggio Java sono i seguenti:
# Un programmatore usa un editor di testo o un [[integrated development environment]] come Eclipse, NetBeans o IntelliJ IDEA per scrivere una o più classi Java
# Un software di compilazione trasforma il programma in bytecode, che è una leggera astrazione del codice macchina
# Il bytecode viene fornito ad una macchina virtuale Java che lo esegue
 
IlTipicamente un programma in formato bytecode èpuò generalmenteessere prodottoottenuto dalla [[compilazione]] di [[codiceun sorgente|codiciprogramma sorgenti]]equivalente (oin un [[Filelinguaggio sorgente|filedi sorgentiprogrammazione]]) scrittidi livello più alto. Tra i vari che possono essere tradotti in linguaggioJava bytecode figurano [[Java (linguaggio di programmazione)|Java]], anche[[Groovy]], se è possibile produrre bytecode partendo da altri linguaggi come[[Clojure]], [[Scala (linguaggio di programmazione)|Scala]], [[Kotlin (linguaggio di programmazione)|Kotlin]], [[Clojure]] o [[Groovy]].<ref>{{Cita web|url = http://zeroturnaround.com/rebellabs/the-adventurous-developers-guide-to-jvm-languages-java-scala-groovy-fantom-clojure-ceylon-kotlin-xtend/|autore = Simon Maple|titolo = heThe Adventurous Developer's Guide to JVM Languages|lingua = en|accesso = 2015-05-30|sito = zeroturnaround.com|nome = Simon|cognome = Maple}}</ref>.
 
== Descrizione ==
La JVM è definita da una [[specifica tecnica|specifica]], mantenuta da [[Oracle Corporation|Oracle]]. Qualsiasi sistema che si comporti in modo coerente con tale specifica viene considerato come una particolare [[implementazione]] della JVM. Esistono implementazioni [[software]] per praticamente tutti i [[sistema operativo|sistemi operativi]] moderni, sia gratuite che commerciali. Inoltre, esistono implementazioni speciali per particolari ambienti [[hardware]]/[[software]], come [[telefono cellulare|telefoni cellulari]] e [[Computer palmare|palmari]]), e persino implementazioni hardware come [[Architettura_ARM#Jazelle|Jazelle]].
 
La JVM è definita da una [[specifica tecnica|specifica]], mantenuta da [[Oracle Corporation|Oracle]]. Qualsiasi sistema che si comporti in modo coerente con tale specifica viene considerato come una particolare [[implementazione]] della JVM. Esistono implementazioni [[software]] per praticamente tutti i [[sistema operativo|sistemi operativi]] moderni, sia gratuite che commerciali. Inoltre, esistono implementazioni speciali per particolari ambienti [[hardware]]/[[software]], come [[telefono cellulare|telefoni cellulari]] e [[Computer palmare|palmari]]), e persino implementazioni hardware come [[Architettura ARM#Jazelle|Jazelle]].
La disponibilità di implementazioni della macchina virtuale Java per diversi ambienti operativi è la chiave della [[portabilità]] di Java, proclamata nello [[slogan]] ''write once, run everywhere'' ("scrivi una volta, esegui dappertutto"). La macchina virtuale realizza infatti un ambiente di esecuzione omogeneo, che nasconde al software Java (e quindi al programmatore) qualsiasi specificità del [[sistema operativo]] sottostante:
 
La disponibilità di implementazioni della macchina virtuale Java per diversi ambienti operativi è la chiave della [[portabilità]] di Java, proclamata nello [[slogan]] ''write once, run everywhere'' ("scrivi una volta, esegui dappertutto"). La macchina virtuale realizza infatti un [[ambiente di esecuzione]] omogeneo, che nasconde al software Java (e quindi al programmatore) qualsiasi specificità del [[sistema operativo]] sottostante:
 
{| border=1 align=center
! Software applicativo Java
|-
! Java Virtual Machine
|-
! Sistema Operativo
|}
 
== Architettura ==
[[File:Java virtual machine architecture.svg|thumb|Schema architetturale di alto livello della JVM]]
 
L'architettura di una JVM comprende in generale i seguenti elementi:
* Un set di istruzioni per i [[bytecode]]
* Un gruppo di [[Registro (informatica)|registri]]
* Uno [[stack (informatica)|stack]]
* Un'area di [[Heap (gestione della memoria)|heap]] su cui opera la routine di [[garbage collection]]
* Un'area per la memorizzazione dei [[Metodo (programmazione)|metodi]]
 
=== Java Bytecode ===
{{vedi anche|Bytecode}}
 
Il [[codice sorgente]] di Java viene [[Compilatore|compilato]] in bytecode e memorizzato in [[file]] con [[Estensione (file)|estensione]] ''.class''. Per compilare tale codice viene fornito uno strumento che prende il nome di [[Javac]]. Questo strumento non viene considerato come un compilatore tradizionale proprio perché traduce il codice sorgente in bytecode. Il codice, a causa del formato, non può essere eseguito direttamente ma deve essere interpretato su ciascun [[computer]]. L'estrema [[portabilità]] e flessibilità del codice Java sono date, appunto, da questo passaggio intermedio.
 
Un'[[Istruzione (informatica)|istruzione]] di bytecode è composta da un [[opcode]] di un [[byte]], che serve per identificare l'istruzione in questione, e da zero o più [[Operando|operandi]], ciascuno dei quali può essere più lungo di un byte.
Quando gli operandi sono più lunghi di un byte, viene memorizzato per primo il [[big-endian]] (byte di ordine superiore), questi operandi vengono poi assemblati dal flusso di byte in fase di esecuzione. Ad esempio, un parametro a [[16 bit]] viene rappresentato all'interno del flusso di istruzioni da due byte.
Il [[set di istruzioni]] della macchina virtuale di Java interpreta i dati nelle aree di memoria di esecuzione come appartenenti a un insieme prefissato di [[Tipo di dato|tipi]]: i tipi primitivi, che sono rappresentati da diversi [[Numero intero (informatica)|tipi interi]] con segno (byte, short, int, long), un tipo intero senza segno (char), due tipi in [[virgola mobile]] (float e double) e in più il tipo che fa riferimento a un [[Oggetto (informatica)|oggetto]] ([[Puntatore (programmazione)|puntatore]] a [[32 bit]]).
 
=== Registri ===
{{vedi anche|Registro (informatica)}}
 
I registri della JVM sono affini ai registri che si trovano in un computer reale, essi contengono lo stato in cui si trova la macchina durante le operazioni, influiscono sul funzionamento di quest'ultima e vengono aggiornati dopo l'esecuzione di ciascun [[bytecode]].
 
La macchina virtuale Java include i seguenti registri:
* pc - il [[program counter]], indica il bytecode che sta per essere eseguito.
* vars - un puntatore alla prima [[Variabile (informatica)|variabile]] locale del metodo attualmente in esecuzione.
* frame - un puntatore all'ambiente di esecuzione del metodo corrente in esecuzione.
* optop - un puntatore al vertice dello stack degli operandi, è utilizzato per valutare tutte le espressioni aritmetiche.
 
L'ampiezza con cui Java definisce questi registri è di 32 bit.
Essendo basata sullo stack, la macchina virtuale non fa alcun uso di registri per il passaggio o l'acquisizione di argomenti; ciò che ha portato i programmatori ad optare per questa scelta è stata la semplicità e la compattezza dei bytecode che favoriscono l'[[Implementare|implementazione]] della macchina virtuale su [[Architettura (computer)|architetture]] con pochi registri.
 
=== Stack ===
Lo [[stack (informatica)|stack]], che è alla base del funzionamento della macchina virtuale Java, viene utilizzato per passare i parametri alle istruzioni che vengono man mano eseguite e per ricevere i risultati da queste prodotti.
Un ''frame'' dello stack di Java è affine a un ''frame'' dello stack di un convenzionale linguaggio di programmazione. Ogni frame contiene le informazioni associate ad una delle chiamate a metodo "impilate" sullo stack.
 
Ogni frame dello stack possiede tre aree (che potrebbero essere anche vuote):
* Le variabili locali per la chiamata al metodo
* L'ambiente di esecuzione del metodo stesso
* Lo stack degli operandi
 
Non si confonda lo stack delle chiamate a metodo con lo stack degli operandi. Quest'ultimo funziona in modo autonomo rispetto all'altro. L'unica correlazione che corre tra i due è che il secondo viene gestito in una area di memoria interna ai frames che sono presenti nel primo. Molto semplicisticamente, potremmo dire che abbiamo a che fare con uno stack nello stack.
 
=== Area di heap ===
Con il termine heap si fa riferimento a quel sito della [[Memoria (informatica)|memoria]] nella quale vengono allocati gli [[Oggetto (informatica)|oggetti]] appena creati.
Al momento dell'avvio della JVM, una certa area di memoria (più ampia o ridotta a seconda dell'implementazione della macchina virtuale) viene spesso assegnata allo heap. Alcune implementazioni assegnano fin dall'avvio una ampia quantità di memoria allo heap, tenendo tale quantità costante per tutta l'esecuzione del programma; altre permettono a quest'area di espandersi fin dove concesso dall'ambiente di esecuzione (tra i fattori che influenzano questa quantità ci sono le impostazioni del sistema operativo e la disponibilità effettiva di memoria sulla macchina che sta eseguendo il programma). Il [[Garbage collector]] è deputato alla rimozione degli oggetti non più utilizzati dal programma man mano che questo è in esecuzione. Ciò consente ai programmatori di svincolarsi dal compito di liberare "manualmente" (inserendo apposite istruzioni nel codice sorgente) la memoria allocata per un oggetto quando quest'ultimo ha esaurito la sua funzione nel programma. Tale compito è addirittura obbligatorio in linguaggi come il [[C++]]. In effetti, il garbage collector è stato progettato proprio per evitare a [[run-time]] quegli errori che derivano dalla mancata [[Allocazione dinamica della memoria|deallocazione]] di memoria non più utilizzata o dal tentativo di deallocare memoria ancora in uso dal programma.
 
=== Area di memorizzazione dei metodi ===
L'area di memorizzazione dei [[Metodo (programmazione)|metodi]] contiene le tabelle dei simboli necessari per il link dinamico, informazioni di [[Debugging|debug]] aggiuntive, ambienti di sviluppo da associare all'implementazione di qualsiasi metodo e i bytecode di Java che implementano tutti i metodi presenti nel sistema. Poiché i bytecode vengono memorizzati come flusso di byte, l'area dei metodi è allineata per byte mentre le altre aree sono allineate a parole di 32 bit.
 
=== Compilazione ''Just-In-Time'' ===
{{Vedi anche|Compilatore just-in-time}}
 
Le prime implementazioni della macchina virtuale Java erano ''[[interprete (informatica)|interpreti]]''. Questa soluzione si è però rivelata poco efficiente, in quanto i programmi interpretati erano comunque molto lenti. Per questo motivo, tutte le implementazioni recenti di macchine virtuali Java hanno incorporato un [[compilatore just-in-time]] (''JIT compiler''), cioè un compilatore interno, che al momento del lancio traduce al volo il programma bytecode Java in un normale programma nel [[linguaggio macchina]] del computer ospite<ref>{{Cita libro|autore = Haase, C.|titolo = Consumer JRE: Leaner, Meaner Java Technology|anno = 2007|editore = Sun Microsystem|città = |accesso = 30 maggio 2015|url = http://www.oracle.com/technetwork/articles/javase/consumerjre-135093.html|lingua = en}}</ref>. Inoltre, questa ricompilazione è dinamica, cioè la macchina virtuale analizza costantemente il modello di esecuzione del codice (''profilattico''), e ottimizza ulteriormente le parti più frequentemente eseguite, mentre il programma è in esecuzione.
 
Questi accorgimenti, a prezzo di una piccola attesa in fase di lancio del programma, permettono di avere delle applicazioni Java decisamente più veloci e leggere. Tuttavia, anche così Java resta un linguaggio meno efficiente dei linguaggi propriamente compilati come il [[C++]], scontando il fatto di possedere degli strati di astrazione in più, e di implementare una serie di automatismi, come il [[garbage collection|garbage collector]], che se da un lato fanno risparmiare tempo ed errori in fase di sviluppo dei programmi, dall'altro consumano [[memoria (informatica)|memoria]] e tempo di [[CPU]] in fase di esecuzione del programma finito.
 
== Implementazioni ==
[[File:Eclipse Adoptium Logo.svg|thumb|[[Adoptium]] è un gruppo di lavoro della [[fondazione Eclipse]] che promuove l'uso delle [[piattaforma Java|tecnologie Java]]. Tra l'altro distribuisce versioni [[file eseguibile|pronte all'uso]] di varie implementazioni della JVM.]]
=== [[OpenJDK]] e HotSpot ===
Oltre a gestire le specifiche della macchina virtuale Java, Oracle fornisce una implementazione chiamata [[HotSpot]] che è gratuita ed in parte open source. La parte non distribuibile riguarda i font, l'audio, la sicurezza e la crittografia<ref>[https://openjdk.java.net/ OpenJDK]</ref><ref>[https://www.documentcloud.org/documents/1157205-13-1021-opinion-5-7-2014-1.html Oracle America vs Google], Corte d'Appello Federale, 9 maggio 2014</ref>; le implementazioni Oracle sono in genere viste come [[implementazione di riferimento|implementazioni di riferimento]], ma sono anche ampiamente utilizzate da utenti finali, aziende e istituzioni.
 
=== IcedTea e ZeroHotSpot ===
{{vedi anche|HotSpot}}
Per sostituire le parti di HotSpot che erano sotto licenza non open, è nato il progetto [[IcedTea]].<ref>Progetto [http://icedtea.classpath.org/wiki/Main_Page IcedTea] {{Webarchive|url=https://web.archive.org/web/20141006113838/http://icedtea.classpath.org/wiki/Main_Page |date=6 ottobre 2014 }}</ref> La macchina virtuale sviluppata in tale progetto si chiama HotSpot Zero Assembly, chiamata anche semplicemente Zero.<ref>[http://icedtea.classpath.org/wiki/ZeroSharkFaq Zero and Shark FAQ]</ref> Il progetto ha anche lo scopo di supportare un numero maggiore di famiglie di processori rispetto alla macchina virtuale di Oracle. Per fare ciò, tutto il codice assembly presente in HotSpot è stato riscritto in C++, in modo da poter essere compilato su più architetture.<ref>[https://today.java.net/pub/a/today/2009/05/21/zero-and-shark-openjdk-port.html Zero and Shark: a Zero-Assembly Port of OpenJDK] {{webarchive|url=https://web.archive.org/web/20141006113630/https://today.java.net/pub/a/today/2009/05/21/zero-and-shark-openjdk-port.html |data=6 ottobre 2014 }}</ref>
[[File:OpenJDK_logo.svg|thumb|[[OpenJDK]] è la principale implementazione [[software libero|libera]] della [[piattaforma Java]]. Include un'implementazione di [[HotSpot]] per la componente JVM.]]
 
HotSpot, ufficialmente nota come ''Java HotSpot Performance Engine''<ref>{{cita web|url=http://www.thefreelibrary.com/Sun+Announces+Availability+of+the+Java+HotSpot+Performance+Engine%3B...-a054477747|urlarchivio=https://web.archive.org/web/20131101095145/http://www.thefreelibrary.com/Sun+Announces+Availability+of+the+Java+HotSpot+Performance+Engine%3B...-a054477747|titolo= Sun Announces Availability of the Java HotSpot Performance Engine|editore=Sun Microsystems|lingua=en}}</ref>
è l'[[implementazione di riferimento]] della JVM, realizzata originariamente da [[Sun Microsystems]] e successivamente gestita da [[Oracle Corporation]].
 
Dal 2006, con la creazione di [[OpenJDK]], HotSpot è [[software libero]].<ref>{{cita web|url=http://www.sun.com/2006-1113/feature/index.jsp|urlarchivio=https://web.archive.org/web/20070421151747/http://www.sun.com/2006-1113/feature/index.jsp|titolo=Sun Opens Java|data=2006-11-13|lingua=en}}</ref>
 
=== Zero ===
Per sostituire le parti di [[OpenJDK]] che erano sotto licenza non open, è nato il progetto [[IcedTea]].<ref>Progetto [http://icedtea.classpath.org/wiki/Main_Page IcedTea] {{Webarchive|url=https://web.archive.org/web/20141006113838/http://icedtea.classpath.org/wiki/Main_Page |date=6 ottobre 2014 }}</ref> La macchina virtuale sviluppata in tale progetto si chiama HotSpot Zero Assembly, chiamata anche semplicemente Zero.<ref>{{Cita web |url=http://icedtea.classpath.org/wiki/ZeroSharkFaq |titolo=Zero and Shark FAQ |accesso=3 ottobre 2014 |dataarchivio=23 agosto 2009 |urlarchivio=https://web.archive.org/web/20090823042123/http://icedtea.classpath.org/wiki/ZeroSharkFaq |urlmorto=sì }}</ref> Il progetto ha anche lo scopo di supportare un numero maggiore di famiglie di processori rispetto alla macchina virtuale di Oracle. Per fare ciò, tutto il codice assembly presente in HotSpot è stato riscritto in C++, in modo da poter essere compilato su più architetture.<ref>[https://today.java.net/pub/a/today/2009/05/21/zero-and-shark-openjdk-port.html Zero and Shark: a Zero-Assembly Port of OpenJDK] {{webarchive|url=https://web.archive.org/web/20141006113630/https://today.java.net/pub/a/today/2009/05/21/zero-and-shark-openjdk-port.html |data=6 ottobre 2014 }}</ref>
 
=== OpenJ9 ===
Eclipse OpenJ9 (precedentemente conosciuta come IBM J9) è un'implementazione scalabile e ad alte performance della JVM, pienamente conforme alla ''Java Virtual Machine Specification''.<ref>{{cita web|url=https://medium.com/criciumadev/new-open-source-jvm-optimized-for-cloud-and-microservices-c75a41aa987d|autore=Leonardo Zanivan|titolo=New Open Source JVM optimized for Cloud and Microservices|data=2018-02-07|lingua=en}}</ref>
 
È parte di varie distribuzioni di [[OpenJDK]], tra cui IBM Semeru.<ref>{{cita web|url=https://developer.ibm.com/blogs/introducing-the-ibm-semeru-runtimes/|titolo=Introducing the IBM Semeru Runtimes|data=2021-08-02|accesso=2024-05-03|lingua=en}}</ref>
 
Rispetto a [[#HotSpot|HotSpot]], OpenJ9 presenta prestazioni migliori in fase di avvio e un minore utilizzo di memoria a livelli di produttività simili.<ref>{{cita web|url=https://jaxenter.com/eclipse-openj9-145182.html|autore=Dan Heidinga|titolo=Eclipse OpenJ9; not just any Java Virtual Machine|data=2018-08-06|accesso=2024-05-03|lingua=en}}</ref>
 
=== Le altre implementazioni ===
Numerose altre parti forniscono regolarmente implementazioni della macchina virtuale Java, in genere con l'intento di competere con l'implementazione Oracle in quanto a prestazioni; in alcuni casi si tratta di implementazioni commerciali. Sono disponibili anche altre implementazioni ''[[open source]]''; fra le più note si può citare Waba<ref>[http://waba.sourceforge.net/php/waba/waba.php Waba]</ref>.
Le specifiche della JVM vengono dettate e aggiornate dalla Oracle in quanto iniziatore e mantenitore del progetto, ma vengono spesso disattese da molte delle implementazioni ''non-Oracle'' di JVM che sono in circolazione, soprattutto per quanto riguarda il [[framework]] che ogni JVM include. Di conseguenza, le diverse JVM non sono totalmente compatibili tra loro ed occorre fare attenzione nello scrivere i programmi, se si vuole che essi funzionino su ogni JVM. La cosa migliore da fare a tale scopo sarebbe non usare le ultime caratteristiche del linguaggio introdotte dalla Oracle nelle JVM più recenti e usare delle [[Application programming interface|API]] "stabili", che cioè siano presenti nella JVM Oracle da varie versioni.
 
== Compilazione ''Just-In-Time'' ==
Le prime implementazioni della macchina virtuale Java erano ''[[interprete (informatica)|interpreti]]''. Questa soluzione si è però rivelata poco efficiente, in quanto i programmi interpretati erano comunque molto lenti. Per questo motivo, tutte le implementazioni recenti di macchine virtuali Java hanno incorporato un [[compilatore just-in-time]] (''JIT compiler''), cioè un compilatore interno, che al momento del lancio traduce al volo il programma bytecode Java in un normale programma nel linguaggio macchina del computer ospite<ref>{{Cita libro|autore = Haase, C.|titolo = Consumer JRE: Leaner, Meaner Java Technology|anno = 2007|editore = Sun Microsystem|città = |accesso = 30 maggio 2015|url = http://www.oracle.com/technetwork/articles/javase/consumerjre-135093.html|lingua = en}}</ref>. Inoltre, questa ricompilazione è dinamica, cioè la macchina virtuale analizza costantemente il modello di esecuzione del codice (''profilattico''), e ottimizza ulteriormente le parti più frequentemente eseguite, mentre il programma è in esecuzione.
 
Questi accorgimenti, a prezzo di una piccola attesa in fase di lancio del programma, permettono di avere delle applicazioni Java decisamente più veloci e leggere. Tuttavia, anche così Java resta un linguaggio meno efficiente dei linguaggi propriamente compilati come il [[C++]], scontando il fatto di possedere degli strati di astrazione in più, e di implementare una serie di automatismi, come il [[garbage collection|garbage collector]], che se da un lato fanno risparmiare tempo ed errori in fase di sviluppo dei programmi, dall'altro consumano [[memoria (informatica)|memoria]] e tempo di [[CPU]] in fase di esecuzione del programma finito.
 
== Note ==
Line 45 ⟶ 110:
* {{Cita libro |titolo = Java Virtual Machine Specification |autore = Tim Lindholm, Frank Yellin, Gilad Bracha, Alex Buckley |url = https://docs.oracle.com/javase/specs/jvms/se8/html/index.html |anno = 2014
|lingua = inglese |edizione = Java SE 8 Edition |accesso = 3 ottobre 2014 }}
* {{Cita libro |titolo = Understanding Java virtual machine |autore = Seth Sachin |url = http://www.alphasci.com/books_display.asp?title=978-1-84265-815-4 |editore = Alpha Science International Ltd |anno = 2013 |lingua = inglese |accesso = 3 ottobre 2014 |urlmorto = sì }}
|lingua = inglese |accesso = 3 ottobre 2014 }}
 
== Voci correlate ==
* [[PortabilitàPiattaforma Java]]
* [[Macchina virtuale]]
* [[NanoVM]]
* [[IJVM]]
 
== Altri progetti ==
{{interprogetto|preposizione=sulla}}
 
== Collegamenti esterni ==
* {{FOLDOC|Java Virtual Machine|Java Virtual Machine}}
 
{{Portale|Informatica}}
 
[[Categoria:Piattaforma Java]]
[[Categoria:Software di sistema]]