L’architettura JVM e come funziona?
Ogni sviluppatore Java sa che il bytecode viene eseguito da JRE , ma JRE è implementazione di JVM. “La macchina virtuale è un’implementazione software della macchina fisica. Java è stata sviluppata con il concetto di WORA (Write Once Run Anywhere).Il compilatore compila il file java in un file di classe, poi il file .class viene inserito nella JVM che lo carica e lo esegue.
Come funziona la JVM?
- Sottosistema del caricatore di classe
- Area dati runtime
- Motore di esecuzione.
Ora, Saltiamo in ogni parte.
1.Class Loader SubSystem :
La funzionalità di caricamento dinamico della classe Java è gestita dal sottosistema class loader. “Load -> Link -> Inizializza il file di classe” per la prima volta a runtime.
1.1. Caricamento: le classi saranno caricate da questo componente.
- Bootstrap Class Loader – carica la classe dal percorso della classe di bootstrap (rt.jar – priorità alta)
- Extension Class Loader – carica la classe inclusa in (jre/lib).
- Application Class Loader – carica la classe a livello di applicazione.
1.2 Linking: Esegue la verifica, la preparazione e la risoluzione sulla classe caricata.
- Verifica: Il verificatore di bytecode verificherà se il bytecode generato è corretto o meno, altrimenti otterremo un errore di verifica (java.lang.VerifyError)
- Preparare: Per tutte le variabili statiche nel bytecode, la memoria sarà allocata e saranno caricati i valori predefiniti.
- Resolve(Optional): I riferimenti simbolici della classe saranno sostituiti con i riferimenti originali dall’area del metodo.
1.3 Inizializzazione: Fase finale del caricatore di classe, qui tutte le variabili statiche saranno assegnate ai valori originali & il blocco statico viene eseguito.
2. Runtime Data Area: (Memoria JVM) – divisa in 5 componenti
- Method Area: questa memorizzerà tutti i dati a livello di classe (campi, metodo, variabile statica). Solo un’area metodo per JVM.
- Area Heap: tutti gli oggetti & istanza corrispondente, variabile, array saranno memorizzati. Un Heap per JVM
- dove Heap & Area Metodo non sono thread safe ma risorse condivise per JVM
3. Area Stack : Per ogni thread verrà creato un nuovo stack a runtime. Per ogni chiamata di metodo, una voce sarà aggiunta nello stack chiamato stack frame.
- La variabile locale sarà memorizzata nella memoria dello stack
- Thread safe
- Stack Frame è diviso in tre entità secondarie:
3.1 Array di variabili locali: relative al metodo locale, le variabili sono invlovate
3.2 Operand Stack: operazione intermedia – agisce come spazio di lavoro runtime per eseguire l’operazione
3.3 Frame Data: tutti i simboli corrispondenti al metodo saranno memorizzati, in caso di qualsiasi eccezione, le informazioni del catch block saranno mantenute.
4. Registri PC: Ogni thread avrà un registro che memorizza l’operazione in corso di esecuzione (una volta che ogni istruzione viene aggiornata, il registro PC aggiornerà anche l’istruzione successiva)
5. Pila del metodo nativo: Tiene le informazioni sul metodo nativo per ogni thread.
3. Execution Engine: Il codice byte che è assegnato nell’area dati Runtime sarà eseguito.
- Interprete: Interpreta il bytecode più velocemente ma lo esegue lentamente.(un metodo è chiamato più volte e crea una nuova interpretazione).
- Compilatore JIT: neutralizza lo svantaggio dell’interprete.ogni volta che trova codice ripetuto usa il compilatore JIT.
Compilerà il bytecode in codice nativo (il codice nativo sarà usato direttamente per le chiamate di metodo ripetute).
Generatore di codice intermedio: Genera codice intermedio quando richiesto
Ottimizzatore di codice: Ottimizza il codice
Generatore di codice target: Converte in codice macchina/nativo
Profiler: Aiuta a trovare le chiamate multiple al metodo (trovare gli hotspot)