Macchina virtuale Java: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
Recupero di 0 fonte/i e segnalazione di 1 link interrotto/i.) #IABot (v2.0.9.5 |
|||
Riga 1:
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]).
Line 22 ⟶ 20:
! 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.
== Implementazioni ==
Line 50 ⟶ 99:
== Voci correlate ==
* [[
* [[Macchina virtuale]]
* [[NanoVM]]
|