logo

Como funciona a JVM - Arquitetura JVM

A Java Virtual Machine (JVM) é um componente central do Java Runtime Environment (JRE) que permite que programas Java sejam executados em qualquer plataforma sem modificação. A JVM atua como um intérprete entre o bytecode Java e o hardware subjacente, fornecendo o famoso recurso Write Once Run Anywhere (WORA) do Java.

  • Fonte Java (.java) -> compilado por javac -> bytecode (.class)
  • JVM carrega o bytecode, verifica se ele o vincula e então o executa
  • A execução pode envolver a interpretação de bytecode ou o uso de compilação Just-In-Time (JIT) para converter código ativo em código de máquina nativo para desempenho
  • A coleta de lixo é executada em segundo plano para recuperar memória de objetos não utilizados

Arquitetura da JVM

A imagem abaixo demonstra a arquitetura e os principais componentes da JVM.

JVM' title=

Componentes da arquitetura JVM

Agora discutiremos cada componente da JVM em detalhes.



1. Subsistema do carregador de classes

É responsável principalmente por três atividades. 

class_loader_subsystem' loading='lazy' title=

1. Carregando

  • Lê arquivos .class e armazena metadados de classe na área de métodos.
  • Cria um objeto Class no heap que representa a classe carregada.
Java
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();  } } 

Saída
Main method started. GFG class is loaded by the JVM! Class loaded successfully. Method of GFG class is executed. 

Observação: Para cada carregado .aula arquivo apenas um objeto da classe é criado.

2. Vinculação: Responsável por preparar a classe carregada para execução. Inclui três etapas:

  • Verificação: Garante que o bytecode siga as regras da JVM e seja seguro para execução.
  • Preparação: Aloca memória para variáveis ​​estáticas e atribui valores padrão.
  • Resolução: Converte referências simbólicas em referências diretas na memória.

3. Inicialização

  • Atribui valores reais a variáveis ​​estáticas.
  • Executa blocos estáticos definidos na classe.

Tipos de carregadores de classes

  • Carregador de classes Bootstrap: Carrega classes Java principais (JAVA_HOME/lib).
  • Carregador de classes de extensão: Carrega classes do diretório de extensões (JAVA_HOME/jre/lib/ext).
  • Carregador de classes de sistema/aplicativo: Carrega classes do caminho de classe do aplicativo.
Java
// 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());  } } 

Saída
null jdk.internal.loader.ClassLoaders$AppClassLoader@8bcc55f 

2. Áreas de memória JVM

  • Área de Método: Armazena informações em nível de classe, como nomes de classe, variáveis ​​de métodos de classe pai e dados estáticos. Compartilhado pela JVM.
  • Área de pilha: Armazena todos os objetos. Compartilhado pela JVM.
  • Área de pilha: Cada thread possui sua própria pilha de tempo de execução; armazena chamadas de método variáveis ​​locais em quadros de pilha. Destruído quando o tópico termina.
  • Registros de PC: Mantém o endereço da instrução atualmente em execução para cada thread.
  • Pilhas de métodos nativos: Cada thread possui uma pilha separada para execução de métodos nativos.

3. Mecanismo de Execução 

O mecanismo de execução executa o .class (bytecode). Ele lê o código de bytes linha por linha, utiliza dados e informações presentes em diversas áreas da memória e executa instruções. Pode ser classificado em três partes:

  • Intérprete: Ele interpreta o bytecode linha por linha e depois executa. A desvantagem aqui é que quando um método é chamado várias vezes, toda vez que a interpretação é necessária.
  • Compilador Just-In-Time (JIT): É usado para aumentar a eficiência de um intérprete. Ele compila todo o bytecode e o altera para código nativo, de modo que sempre que o intérprete vê chamadas de método repetidas, o JIT fornece código nativo direto para essa parte, de modo que a reinterpretação não é necessária e, portanto, a eficiência é melhorada.
  • Coletor de lixo: Ele destrói objetos não referenciados. Para mais informações sobre Coletor de Lixo, consulte Coletor de lixo .

4. Interface Nativa Java (JNI)

É uma interface que interage com as bibliotecas de métodos nativos e fornece as bibliotecas nativas (C C++) necessárias para a execução. Ele permite que a JVM chame bibliotecas C/C++ e seja chamada por bibliotecas C/C++ que podem ser específicas do hardware.

5. Bibliotecas de métodos nativos

Estas são coleções de bibliotecas nativas necessárias para executar métodos nativos. Eles incluem bibliotecas escritas em linguagens como C e C++.

10 de 1 milhão