La màquina virtual de Java (JVM) és un component bàsic del Java Runtime Environment (JRE) que permet que els programes Java s'executin en qualsevol plataforma sense modificacions. JVM actua com a intèrpret entre el codi de bytes de Java i el maquinari subjacent que proporciona la famosa capacitat Write Once Run Anywhere (WORA) de Java.
python converteix bytes en cadena
- Font Java (.java) -> compilat per javac -> bytecode (.class)
- JVM carrega el bytecode verifica que l'enllaça i després l'executa
- L'execució pot implicar la interpretació del bytecode o l'ús de la compilació Just-In-Time (JIT) per convertir el codi calent en codi de màquina natiu per obtenir un rendiment.
- La recollida d'escombraries s'executa en segon pla per recuperar la memòria dels objectes no utilitzats
Arquitectura de JVM
La imatge següent mostra l'arquitectura i els components clau de JVM.
Components de l'arquitectura JVM
Ara parlarem de cada component de la JVM en detall.
1. Subsistema de càrrega de classes
S'encarrega principalment de tres activitats.
1. Càrrega
- Llegeix fitxers .class i emmagatzema metadades de classe a l'àrea de mètodes.
- Crea un objecte Class a la pila que representa la classe carregada.
class GFG{ static{ System.out.println('GFG class is loaded by the JVM!'); } public void display(){ System.out.println('Method of GFG class is executed.'); } } public class Test{ public static void main(String[] args) throws Exception{ System.out.println('Main method started.'); // Loading the class explicitly using Class.forName() Class.forName('GFG'); System.out.println('Class loaded successfully.'); // Creating object to execute method GFG obj = new GFG(); obj.display(); } }
Sortida
Main method started. GFG class is loaded by the JVM! Class loaded successfully. Method of GFG class is executed.
Nota: Per cada carregat .classe només fitxer un es crea l'objecte de la classe.
2. Enllaç: Responsable de preparar la classe carregada per a l'execució. Inclou tres passos:
- Verificació: Assegura que el bytecode segueix les regles de la JVM i és segur d'executar.
- Preparació: Assigna memòria per a variables estàtiques i assigna valors per defecte.
- Resolució: Converteix referències simbòliques en referències directes a la memòria.
3. Inicialització
- Assigna valors reals a variables estàtiques.
- Executa els blocs estàtics definits a la classe.
Tipus de carregador de classes
- Carregador de classe Bootstrap: Carrega les classes bàsiques de Java (JAVA_HOME/lib).
- Carregador de classes d'extensió: Carrega les classes des del directori d'extensions (JAVA_HOME/jre/lib/ext).
- Carregador de classes de sistema/aplicació: Carrega les classes des del classpath de l'aplicació.
// Java code to demonstrate Class Loader subsystem public class Geeks { public static void main(String[] args) { // String class is loaded by bootstrap loader and // bootstrap loader is not Java object hence null System.out.println(String.class.getClassLoader()); // Test class is loaded by Application loader System.out.println(Geeks.class.getClassLoader()); } }
Sortida
null jdk.internal.loader.ClassLoaders$AppClassLoader@8bcc55f
2. Àrees de memòria JVM
- Àrea del mètode: Emmagatzema informació a nivell de classe, com ara el nom de classe, les variables dels mètodes de classe pare i les dades estàtiques. Compartit a través de la JVM.
- Àrea d'heap: Emmagatzema tots els objectes. Compartit a través de la JVM.
- Àrea de pila: Cada fil té la seva pròpia pila d'execució; El mètode stores crida variables locals en marcs de pila. Destruït quan s'acaba el fil.
- Registres de PC: Manteniu l'adreça de la instrucció que s'està executant actualment per a cada fil.
- Piles de mètodes natius: Cada fil té una pila independent per a l'execució del mètode natiu.
3. Motor d'execució
El motor d'execució executa el .class (codi de bytes). Llegeix el codi de byte línia per línia utilitza dades i informació presents a diverses àrees de memòria i executa instruccions. Es pot classificar en tres parts:
- Intèrpret: Interpreta el bytecode línia per línia i després s'executa. El desavantatge aquí és que quan un mètode es crida diverses vegades cada vegada que es requereix una interpretació.
- Compilador just a temps (JIT): S'utilitza per augmentar l'eficiència d'un intèrpret. Compila tot el bytecode i el canvia a codi natiu, de manera que cada vegada que l'intèrpret veu trucades de mètodes repetides, JIT proporciona codi natiu directe per a aquesta part, de manera que no cal la reinterpretació, per tant es millora l'eficiència.
- Recollidor d'escombraries: Destrueix objectes no referenciats. Per obtenir més informació sobre Garbage Collector, consulteu Recollidor d'escombraries .
4. Interfície nativa de Java (JNI)
És una interfície que interactua amb les biblioteques de mètodes natius i proporciona les biblioteques natives (C C++) necessàries per a l'execució. Permet que JVM cridi biblioteques C/C++ i sigui cridat per biblioteques C/C++ que poden ser específiques del maquinari.
5. Biblioteques de mètodes natius
Aquestes són col·leccions de biblioteques natives necessàries per executar mètodes natius. Inclouen biblioteques escrites en llenguatges com C i C++.