Cada item acima será detalhado de forma sucinta, pois o objetivo final é o entendemento geral do mecanismos de uma JVM.
- Carregador de classes (Classloader): Responsável por carregar, ligar (“link”) e inicializar variáveis. Devem verificar a integridade de um “class file” antes de carregá-lo, podendo inclusive reconhecer outros tipos de arquivo além do “class file”. Ao carregar uma classe, uma instancia da classe java.lang.Class ´e criada passando a habitar a heap. Habitam a heap também, assim como todos os objetos, instancias de “User-defined class loaders” e instancias de java.lang.Class. Dados para tipos carregados ficam na área de métodos. Pode ser de dois tipos: “Bootstrap Class Loader”, parte da JVM responsável por carregar classes da API de Java, e “User-defined class loaders”, implementados por uma aplicação;
o User-defined class loader: pode basicamente invocar o “Bootstrap Class Loader”, através do método findSystemClass,carregar uma classe a partir de seu class file (defineClass) e ligá-la (resolveClass). Pode ser utilizado, por exemplo, para construir um interpretador que primeiro gera o “bytecode” de um programa, isto a representação class file de um programa e depois cria uma classe associada a representação class file, podendo também escrevê-la para disco tornando-a persistente;
o Namespace: Cada class loader define um. Com isto um determinado tipo pode ser carregado duas ou mais vezes numa mesma instância da máquina virtual, desde que estejam em namespaces diferentes;
- Rotina de tempo de execução (Runtime): A Maquina Virtual Java define varias áreas de dados em tempo de execução as quais são usadas durante a execução de um programa. Algumas dessas áreas de dados são criadas na inicialização da Máquina Virtual Java e são destruídas apenas quando a Máquina Virtual Java acaba seu processo. Outras áreas de dados são por threads. Áreas de dados por threads são criadas quando uma thread é criada e são destruídas quando a thread termina seu processo;
- Área de processo ou processamento:
- Pilha de métodos nativos (Native Methotd Stack): (Per-thread) São Frequentemente chamados de - "C Stacks" -Porque a maneira mais comum de se escrever métodos Nativos é escrever em c e depois os compilarem em métodos nativos. A jvm em si, conhece várias Linguagens de programação sendo assim, Quando você for fazer algo em Java, que realmente não tenha como, você tem suporte ao faze-lo em outras linguagens de programação;
- Pilha Java (Java Stack): Normalmente a nomenclatura a Java Virtual Machine Stacks se resume Em "STACK". Cada processo tem ao menos uma thread, uma thread em um contexto geral é um STACK. Então cada thread é um STACK. É usada para passar parâmetros e retornar parâmetros de métodos e manter o estado dos métodos(que são chamados de Stack Frame)
- Contador de registro (Program Counter Register):
- Dados de execução: este bloco é compartilhado entre todos os processos e é composta por duas áreas:
- Área de métodos (Method Area): É uma área dividida por todas as threads. É onde ficam os bytecodes. É onde o Program Counter usa para dizer em qual linha de instrução a thread esta. Depois que uma instrução é concluída, o pc referente a thread vai agora conter (apontar) para a próxima instrução que será executada e assim por vez. Então o - pc- do Pc Register Aponta para os byteCodes da method Area. É uma área que armazena estruturas per-class, CONTEM tabelas como a Runtime Constant Pool, armazena fields, métodos, além da lógica em bytecodes entre outros;
- Heap: Objetos e vetores são alocados dinamicamente na heap, quando da execução de uma aplicação Java. A heap ´e compartilhada numa JVM, ou seja, diferentes threads numa mesma aplicacao devem então gerenciar a sincronização no acesso a objetos por estes serem alocados na heap;
- A heap é gerenciada por um garbage colector sendo então desnecessária a deslocação explícita de objetos da heap. O garbage colector gerencia também a fragmentação da heap. É interessante notar que a especificação da JVM não impõe o uso de uma política de coleção de lixo particular nem mesmo a implementação de um coletor de lixo: só fica especificado que não existe uma deslocação explícita de memória e que a JVM deve então resolver isso de alguma maneira, podendo simplesmente dizer que a memória acabou.
- A representação dos objetos na heap também não fica definida pela JVM: devem no entanto conter as variáveis de instancia e uma referencia a method area para acesso as informações estáticas do tipo que ficam armazenadas naquela área assim como permitir a consulta ao tipo para uma coerção de tipos (“typecasting”), execução do comando instance of e para resolução do binding dinâmico: a escolha do m´método a ser executado depende não da instˆancia mas do seu tipo.
- Esquemas de memória para a heap devem levar em consideração:
§ Como ´e o acesso as informações do tipo a partir de uma instancia.
§ Uso ou não de tabela de métodos para agilizar a chamada de métodos. (Similar às tabelas virtuais em C++). Agilizam o acesso aos métodos porém implicam no uso de mais memória.
§ “Lock” do objeto para no acesso multi-threaded.
§ “Wait set” do objeto, representando um conjunto de threads que esperam por acesso a um objeto. Informações necessárias ao garbage collector.
- O tamanho de um vetor (“array”) não influencia no seu tipo, isto é, um vetor de inteiros de tamanho três tem o mesmo tipo de um vetor de tamanho 100. A informação sobre o tamanho do vetor fica armazenada internamente na instancia, devendo fazer parte então da estrutura de representação do objeto.
- Motor de execução (Execution Engine): mecanismo responsável pela execução dos métodos das classes carregadas.
- Interface Nativa Java (JNI): usada na declaração de métodos que não são implementados em nenhuma classe Java. Ela serve para indicar à Java Virtual Machine (JVM) que, quando o método for chamado, o código que se deseja executar está em uma biblioteca, implementada com linguagem de programação nativa de um sistema, normalmente C e C++;
- Bibliotecas Nativas (Native Libraries): é um conjunto de bibliotecas feitas especificamente para rodar os programas em Java num determinado sistema operacional. Um conjunto de rotinas que interpreta o byte code feito em Java para o sistema operacional. Ela oferece rotinas para todos os itens acima, podemos dizer que estas bibliotecas são o próprio Java. Existe uma para cada tipo de sistema operacional.