Java Virtual Machine - Áreas de dados em tempo de execução
A especificação JVM define certas áreas de dados de tempo de execução que são necessárias durante a execução do programa. Alguns deles são criados durante a inicialização da JVM. Outros são locais para threads e são criados apenas quando um thread é criado (e destruídos quando o thread é destruído). Eles estão listados abaixo -
Registro de PC (contador de programa)
É local para cada encadeamento e contém o endereço da instrução JVM que o encadeamento está executando atualmente.
Pilha
É local para cada thread e armazena parâmetros, variáveis locais e endereços de retorno durante chamadas de método. Um erro StackOverflow pode ocorrer se um thread exigir mais espaço de pilha do que o permitido. Se a pilha for expansível dinamicamente, ela ainda pode lançar OutOfMemoryError.
Heap
É compartilhado entre todos os threads e contém objetos, metadados de classes, matrizes, etc., que são criados durante o tempo de execução. Ele é criado quando o JVM é iniciado e é destruído quando o JVM é encerrado. Você pode controlar a quantidade de heap que sua JVM exige do sistema operacional usando certos sinalizadores (mais sobre isso posteriormente). É preciso ter cuidado para não exigir muito menos ou muito da memória, pois isso tem implicações importantes no desempenho. Além disso, o GC gerencia este espaço e remove continuamente objetos mortos para liberar o espaço.
Área de Método
Esta área de tempo de execução é comum a todos os encadeamentos e é criada quando a JVM é inicializada. Ele armazena estruturas por classe, como o pool de constantes (mais sobre isso mais tarde), o código para construtores e métodos, dados de método, etc. A JVM pode escolher ignorar o GC. Além disso, isso pode ou não se expandir de acordo com as necessidades do aplicativo. O JLS não impõe nada com relação a isso.
Pool constante de tempo de execução
A JVM mantém uma estrutura de dados por classe / por tipo que atua como a tabela de símbolos (uma de suas muitas funções) ao vincular as classes carregadas.
Pilhas de método nativo
Quando um encadeamento invoca um método nativo, ele entra em um novo mundo no qual as estruturas e restrições de segurança da máquina virtual Java não mais atrapalham sua liberdade. Um método nativo provavelmente pode acessar as áreas de dados de tempo de execução da máquina virtual (depende da interface do método nativo), mas também pode fazer qualquer outra coisa que desejar.
Coleta de lixo
A JVM gerencia todo o ciclo de vida dos objetos em Java. Depois que um objeto é criado, o desenvolvedor não precisa mais se preocupar com isso. Caso o objeto fique morto (isto é, não haja mais referência a ele), ele é ejetado da pilha pelo GC usando um dos muitos algoritmos - GC serial, CMS, G1, etc.
Durante o processo de GC, os objetos são movidos na memória. Conseqüentemente, esses objetos não podem ser usados durante o processo. Todo o aplicativo deve ser interrompido durante o processo. Essas pausas são chamadas de pausas de 'parar o mundo' e são uma grande sobrecarga. Os algoritmos de GC visam principalmente reduzir esse tempo. Discutiremos isso em grande detalhe nos capítulos seguintes.
Graças ao GC, os vazamentos de memória são muito raros em Java, mas podem acontecer. Veremos nos capítulos posteriores como criar um vazamento de memória em Java.