Java Virtual Machine - Aree dati di runtime
La specifica JVM definisce alcune aree di dati di runtime necessarie durante l'esecuzione del programma. Alcuni di essi vengono creati durante l'avvio della JVM. Altri sono locali nei thread e vengono creati solo quando viene creato un thread (e distrutti quando il thread viene distrutto). Questi sono elencati di seguito:
Registro PC (contatore programma)
È locale per ogni thread e contiene l'indirizzo dell'istruzione JVM che il thread sta attualmente eseguendo.
Pila
È locale per ogni thread e memorizza parametri, variabili locali e indirizzi di ritorno durante le chiamate al metodo. Un errore StackOverflow può verificarsi se un thread richiede più spazio dello stack di quanto consentito. Se lo stack è espandibile dinamicamente, può comunque generare OutOfMemoryError.
Mucchio
È condiviso tra tutti i thread e contiene oggetti, metadati delle classi, array, ecc. Che vengono creati durante il runtime. Viene creato all'avvio della JVM e viene distrutto quando la JVM si arresta. È possibile controllare la quantità di heap richiesta dalla JVM dal sistema operativo utilizzando determinati flag (ne parleremo più avanti). Bisogna fare attenzione a non richiedere troppo meno o troppo della memoria, poiché ha importanti implicazioni sulle prestazioni. Inoltre, il GC gestisce questo spazio e rimuove continuamente gli oggetti morti per liberare lo spazio.
Area del metodo
Questa area di runtime è comune a tutti i thread e viene creata all'avvio della JVM. Memorizza strutture per classe come il pool di costanti (ne parleremo più avanti), il codice per costruttori e metodi, dati di metodo, ecc. JLS non specifica se quest'area deve essere garbage collection e quindi JVM può scegliere di ignorare GC. Inoltre, questo può o meno espandersi in base alle esigenze dell'applicazione. Il JLS non impone nulla al riguardo.
Pool costante di tempo di esecuzione
La JVM mantiene una struttura dati per classe / per tipo che funge da tabella dei simboli (uno dei suoi numerosi ruoli) mentre collega le classi caricate.
Stack di metodi nativi
Quando un thread invoca un metodo nativo, entra in un nuovo mondo in cui le strutture e le restrizioni di sicurezza della Java virtual machine non ne ostacolano più la libertà. Un metodo nativo può probabilmente accedere alle aree dati di runtime della macchina virtuale (dipende dall'interfaccia del metodo nativo), ma può anche fare qualsiasi altra cosa desideri.
Raccolta dei rifiuti
La JVM gestisce l'intero ciclo di vita degli oggetti in Java. Una volta creato un oggetto, lo sviluppatore non deve più preoccuparsene. Nel caso in cui l'oggetto diventi morto (ovvero, non vi è più alcun riferimento ad esso), viene espulso dall'heap dal GC utilizzando uno dei tanti algoritmi: GC seriale, CMS, G1, ecc.
Durante il processo GC, gli oggetti vengono spostati in memoria. Quindi, quegli oggetti non sono utilizzabili mentre il processo è in corso. L'intera applicazione deve essere interrotta per la durata del processo. Tali pause sono chiamate pause "stop-the-world" e sono un enorme sovraccarico. Gli algoritmi GC mirano principalmente a ridurre questo tempo. Discuteremo questo in dettaglio nei capitoli seguenti.
Grazie al GC, le perdite di memoria sono molto rare in Java, ma possono verificarsi. Vedremo nei capitoli successivi come creare una perdita di memoria in Java.