1 visão geral
Java é conhecido por suportar mobilidade agnóstica, de segurança e rede da plataforma. A plataforma Java é composta por Máquinas Virtuais Java e Classes Core Java, que fornece uma interface de programação unificada para programas Java Pure, independentemente do sistema operacional inferior. É precisamente por causa da máquina virtual Java que sua reivindicação é "compilada uma vez, executada em todos os lugares" pode ser garantida.
1.1 Processo de execução do programa Java
A execução dos programas Java depende do ambiente de compilação e do ambiente de corrida. O código -fonte é convertido em código de máquina executável, que é concluído pelo seguinte processo:
O núcleo da tecnologia Java é a máquina virtual Java, porque todos os programas Java são executados na máquina virtual. A operação dos programas Java requer a cooperação da Java Virtual Machine, Java API e Java Class. A instância do Java Virtual Machine é responsável por executar um programa Java. Quando um programa Java é iniciado, uma instância de máquina virtual nasce. Quando o programa termina, a instância da máquina virtual morre.
O recurso de plataforma cruzada da Java é porque possui máquinas virtuais direcionadas a diferentes plataformas.
1.2 Máquina Virtual Java
A principal tarefa de uma máquina virtual Java é carregar arquivos de classe e executar os códigos de bytes. Como pode ser visto na figura abaixo, a máquina virtual Java contém um carregador de classe, que pode carregar arquivos de classe de programas e APIs. Somente classes necessárias para a execução do programa serão carregadas na API Java, e o bytecode é executado pelo mecanismo de execução.
Quando uma máquina virtual Java é implementada por software no sistema operacional host, o programa Java interage com o host chamando métodos locais. Os métodos Java são escritos no idioma Java, compilados no bytecode e armazenados em arquivos de classe. O método local é escrito na linguagem C/C ++/Assembly, compilada em código de máquina relacionado ao processador, armazenado na biblioteca de links dinâmicos, e o formato é proprietário de cada plataforma. Portanto, o método local é conectar os programas Java ao sistema operacional host subjacente.
Como a máquina virtual Java não sabe como um arquivo de classe foi criado e se foi adulterado, ele implementa um detector de arquivo de classe para garantir que os tipos definidos no arquivo de classe possam ser usados com segurança. O verificador de arquivo da classe garante a robustez do programa através de quatro varreduras independentes:
・ Coleção de arquivo de classe
・ Verificação semântica dos dados do tipo
・ Verificação de bytecode
・ Verificação de referência do símbolo
Ao executar o bytecode, as máquinas virtuais Java também executam outros mecanismos de segurança internos. São as características de garantir a robustez dos programas Java como linguagens de programação Java e também são as características das máquinas virtuais Java:
・ Conversão de referência à segura do tipo
・ Acesso à memória estruturada
・ Coleção automática de lixo
・ Verificação de limite da matriz
・ Verificação de cotação vazia
1.3 Java Virtual Machine Data Type
As máquinas virtuais Java executam cálculos por meio de determinados tipos de dados. Os tipos de dados podem ser divididos em dois tipos: tipos básicos e tipos de referência, como mostrado na figura abaixo:
Mas Boolean é um pouco especial. Quando o compilador compila o código -fonte Java no bytecode, ele representará booleano com int ou byte. Nas máquinas virtuais de Java, False é representado por 0, e True é representado por todos os números inteiros diferentes de zero. Como o idioma Java, o intervalo de valor do tipo básico de uma máquina virtual Java é consistente em todos os lugares, independentemente da plataforma host, um longo é sempre um número inteiro assinado com complemento de 64 bits em qualquer máquina virtual.
Para ReturnAddress, esse tipo básico é usado para implementar a cláusula finalmente em um programa Java. Os programadores Java não podem usar esse tipo, seu valor aponta para o código de opção de uma instrução da máquina virtual.
2architecture
Na especificação da máquina virtual Java, o comportamento de uma instância da máquina virtual é descrito em termos de subsistema, área de memória, tipo de dados e instruções, e esses componentes juntos mostram a arquitetura interna da máquina virtual abstrata.
2.1 Classe Arquivo
O arquivo javaclass contém todas as informações sobre uma classe ou interface. O "tipo base" do arquivo de classe é o seguinte:
| U1 | 1 byte, tipo não assinado |
| U2 | 2 bytes, tipo não assinado |
| u4 | 4 bytes, tipo não assinado |
| U8 | 8 bytes, tipo não assinado |
Se você quiser saber mais, o JVM SE7 da Oracle fornece a especificação oficial: a especificação da máquina virtual Java®
O conteúdo do arquivo de classe:
ClassFile {U4 Magic; // Número mágico: 0xcafeBabe, usado para determinar se é um arquivo de classe Java U2 Minor_version; // Número da versão menor u2 major_version; // Número da versão principal U2 constant_pool_count; // tamanho constante do pool cp_info constant_pool [constant_pool_count-1]; // Pool constante u2 access_flags; // sinalizadores de acesso nos níveis de classe e interface (obtidos através da | operação) u2 this_class; // Índice de classe (apontando para constantes de classe no pool constante) u2 super_class; // Apresentar índice de classe (apontando para constantes de classe em pool constante) U2 interfaces_count; // interfaces Index Counter U2 Interfaces [interfaces_count]; // ÍNDICE DE INTERFACE SET U2 FIELDS_COUNT; // Campo de contagem de campo Campos Counter_info [campos_count]; // tabela de campo Defina U2 Methods_Count; // Método contagem contador métodos_info Métodos [Methods_Count]; // tabela de métodos Defina U2 Atributes_Count; // número de atributo attribute_info atributos [attributes_count]; // Tabela de atributos} 2.2 Subsistema de carregador de classe
O subsistema de carregadores de classe é responsável por encontrar e carregar informações do tipo. De fato, existem dois tipos de carregadeiras para máquinas virtuais Java: carregadores de sistema e carregadores definidos pelo usuário. O primeiro faz parte da implementação da Java Virtual Machine, enquanto o último faz parte do programa Java.
・ BootstrapClassLoader: é usado para carregar a biblioteca principal do Java, implementado no código nativo e não é herdado de java.lang.classloader.
・ ExtensionClassLoader: é usado para carregar bibliotecas de extensão Java. A implementação da máquina virtual Java fornecerá um diretório de biblioteca de extensão. Este carregador de classe procura e carrega as classes Java neste diretório.
・ Classe de aplicativo Loader: ele carrega classes Java de acordo com o aplicativo ClassPath of Java (ClassPath). De um modo geral, as classes de aplicativos Java são carregadas por ele. Pode ser obtido através do ClassLoader.GetSystemClassLoader ().
Além dos carregadores de classe fornecidos pelo sistema, os desenvolvedores podem implementar seus próprios carregadores de classe herdando a classe java.lang.classloader para atender a algumas necessidades especiais.
O subsistema de carregadores de classe envolve vários outros componentes da máquina virtual Java e as classes da biblioteca Java.lang. O método definido pelo Classloader fornece uma interface para o programa acessar o mecanismo de carregador de classe. Além disso, para cada tipo carregado, a máquina virtual Java cria uma instância da classe java.lang.class para representar o tipo. Como outros objetos, os carregadores de classe definidos pelo usuário e instâncias de classe são colocados na área de heap na memória, enquanto as informações do tipo carregado estão localizadas na área do método.
Além de localizar e importar arquivos de classe binária, o subsistema de carregador de classe também deve ser responsável por verificar a correção da classe importada, alocar e inicializar a memória para variáveis de classe e analisar referências simbólicas. Essas ações também precisam ser executadas na seguinte ordem:
・ Carga (encontre e carrega dados binários do tipo)
・ Conexão (verificação de execução: Garanta a correção do tipo importado; preparação: alocar memória para variáveis de classe e inicialize -as para valores padrão; análise: converter referências simbólicas no tipo em referências diretas)
・ Inicialização (as variáveis de classe são inicializadas com o valor inicial correto)
2.3 Área do método
Em uma máquina virtual Java, as informações sobre o tipo carregado são armazenadas na memória em uma área de método. Quando uma máquina virtual carrega um determinado tipo, ele usa um carregador de classe para localizar o arquivo de classe correspondente, lê o arquivo de classe e o transfere para a máquina virtual. Em seguida, a máquina virtual extrai as informações de tipo e armazena essas informações na área do método. As áreas de método também podem ser coletadas pelo coletor de lixo, porque a máquina virtual permite a extensão dinâmica dos programas Java por meio de carregadores de classe definidos pelo usuário.
As informações a seguir são armazenadas na área de método:
・ Este tipo de nome totalmente qualificado (como o nome totalmente qualificado java.lang.Object)
・ O nome totalmente qualificado desse tipo de superclasse direta
・ Este tipo de classe de tipo ou tipo de interface
・ Este tipo de modificador de acesso (um subconjunto de público, resumo, final)
・ Lista classificada de nomes totalmente qualificados para qualquer hiperinterface direta
・ Pool constante desse tipo (uma coleção ordenada, incluindo constantes diretas [string, constantes inteiros e flutuantes] e referências simbólicas a outros tipos, campos e métodos)
・ Informações de campo (nome de campo, tipo, modificador)
・ Informações do método (nome do método, tipo de retorno, número de parâmetros e tipo, modificador)
・ Todas as variáveis de classe (estática), exceto constantes
・ Referência à classe Classloader (quando cada tipo é carregado, a máquina virtual deve rastrear se é carregado pelo carregador de classe de inicialização ou pelo carregador de classe definido pelo usuário)
・ Referência à classe Class (Para cada tipo carregado, a máquina virtual criará uma instância da classe Java.lang.class de acordo. Por exemplo, se você tiver uma referência ao objeto do Java.lang.integer Classe, então você precisa ser chamado de Método.
2.4 Heap
Todas as instâncias de classe ou matrizes criadas pelos programas Java no tempo de execução (as matrizes são um objeto real em uma máquina virtual Java) são colocadas na mesma pilha. Como as instâncias da Java Virtual Machine possuem apenas um espaço de heap, todos os threads compartilharão esse heap. Deve -se notar que a máquina virtual Java tem uma instrução para alocar objetos na pilha, mas não tem uma instrução para liberar a memória, porque a máquina virtual entregou essa tarefa ao coletor de lixo para processamento. A especificação Java Virtual Machine não aplica coletores de lixo, exige apenas que as implementações de máquinas virtuais devem gerenciar seu próprio espaço "de alguma forma". Por exemplo, uma implementação pode ter apenas um espaço de heap de tamanho fixo. Quando o espaço é preenchido, ele simplesmente lança uma exceção excelente, que não considera a questão da reciclagem de objetos de lixo, mas cumpre as especificações.
A especificação Java Virtual Machine não especifica como os objetos Java são representados na pilha, o que fornece ao implementador as decisões da máquina virtual sobre como projetar. Um possível design de heap é o seguinte:
Uma piscina de alça, um pool de objetos. A referência de um objeto é um ponteiro local para o pool de alça. Os benefícios desse design são propícios à classificação de fragmentos de heap. Ao mover objetos no pool de objetos, a parte da alça só precisa alterar o novo endereço do ponteiro apontando para o objeto. A desvantagem é que cada vez que uma variável de instância de um objeto é acessada, ela deve ser passada através de dois ponteiros.
2.5 pilha java
Sempre que um thread é iniciado, a máquina virtual Java aloca uma pilha Java. Uma pilha Java consiste em muitos quadros de pilha, um quadro de pilha contém o estado de uma chamada de método Java. Quando um thread chama um método Java, a máquina virtual empurra um novo quadro de pilha para a pilha Java do thread. Quando o método retorna, a estrutura da pilha aparece da pilha Java. A pilha Java armazena o status do método Java chama em threads - incluindo variáveis locais, parâmetros, valores de retorno e resultados intermediários de operações, etc. As máquinas virtuais Java não possuem registros e seu conjunto de instruções usa uma pilha Java para armazenar dados intermediários. O motivo desse design é manter o conjunto de instruções da máquina virtual Java o mais compacta possível e também facilitar a implementação da máquina virtual Java em uma plataforma com poucos registros gerais. Além disso, a arquitetura baseada em pilha também ajuda a otimizar o código de compiladores dinâmicos e compiladores instantâneos implementados por certas máquinas virtuais durante o tempo de execução.
2.5.1 quadro de pilha
Um quadro de pilha consiste em uma área variável local, uma pilha de operando e uma área de dados de quadros. Quando uma máquina virtual chama um método Java, ele obtém a área variável local e o tamanho da pilha do operando desse método a partir da informação de tipo da classe correspondente e aloca a memória do quadro da pilha de acordo com isso e depois a empurra para a pilha Java.
2.5.1.1 Área variável local
A área variável local é organizada em uma matriz contada de 0 em unidades de comprimento da palavra. A instrução de bytecode usa os dados nele através de um índice a partir de 0. Valores de tipos int, flutuam, referência e retorno -adddress Occupy um item na matriz, enquanto os valores dos tipos de byte, curto e char são convertidos em valores int antes de serem armazenados na matriz e também ocupam um item. Mas valores de tipos de longa e dupla ocuparam dois termos consecutivos na matriz.
2.5.1.2 Pilha de operando
Como a área variável local, a pilha de operando também é organizada em uma matriz no comprimento da palavra. Ele acessa através da pilha de operações de pilha padrão e empilham. Como o contador do programa não pode ser acessado diretamente pelas instruções do programa, as instruções da máquina virtual Java obtêm operandos da pilha de operando, de modo que sua operação é baseada na pilha e não nos registros. A máquina virtual toma a pilha de operando como espaço de trabalho, porque a maioria das instruções precisa exibir dados daqui, executar operações e depois empurrar o resultado de volta à pilha de operando.
2.5.1.3 Área de dados do quadro
Além da área variável local e da pilha de operando, os quadros de pilha Java também precisam de áreas de dados de quadros para suportar análises constantes do pool, retorno normal do método e mecanismos de despacho de exceção. Sempre que uma máquina virtual deseja executar uma instrução que requer dados constantes do pool, ela os acessa através de um ponteiro para o pool constante na área de dados do quadro. Além da análise de pools constantes, a área de dados de quadros também ajuda a máquina virtual a lidar com a extremidade normal ou o aborto anormal dos métodos Java. Se o retorno terminar normalmente, a máquina virtual deverá restaurar o quadro da pilha do método iniciando a chamada, incluindo definir o contador do programa para apontar para a próxima instrução iniciando o método de chamada; Se o método tiver um valor de retorno, a máquina virtual precisará empurrá -lo para a pilha de operando do método iniciando a chamada. Para lidar com as saídas de exceção durante a execução do método Java, a área de dados do quadro também mantém uma referência à tabela de exceção desse método.
2.6 Contador de programas
Para um programa Java em execução, cada thread possui seu contador de programas. Os contadores de programas também são chamados de registros de PC. O contador do programa pode conter um ponteiro local e um retorno. Quando um thread executa um método Java, o valor do contador do programa é sempre o endereço da próxima instrução executada. O endereço aqui pode ser um ponteiro local ou um deslocamento no bytecode do método em relação à instrução de início do método. Se o thread estiver executando um método local, o valor do contador do programa será "indefinido".
2.7 pilha de métodos locais
Qualquer interface de método local usará algum tipo de pilha de métodos locais. Quando um thread chama um método Java, a máquina virtual cria uma nova estrutura de pilha e o empurra para a pilha Java. Quando chama um método local, a máquina virtual mantém a pilha Java inalterada e não é mais empurra para a nova pilha na pilha Java rosqueada. A máquina virtual simplesmente se conecta dinamicamente e diretamente chama o método local especificado.
A área do método e a pilha são compartilhados por todos os threads na instância da máquina virtual. Quando a máquina virtual carrega um arquivo de classe, ele analisa as informações de tipo dos dados binários contidos no arquivo de classe e, em seguida, coloca as informações de tipo na área do método. Quando o programa está em execução, a máquina virtual coloca todos os objetos criados pelo programa no tempo de execução no heap.
Como outras áreas de memória de tempo de execução, a área de memória ocupada pela pilha de métodos local pode ser expandida dinamicamente ou encolhida conforme necessário.
3 Motor de execução
Na especificação da máquina virtual Java, o comportamento do mecanismo de execução é definido usando conjuntos de instruções. O designer que implementa o mecanismo de execução decidirá como executar o bytecode, a implementação pode ser interpretada, compilada em tempo ou executada diretamente usando instruções no chip ou uma mistura deles.
O mecanismo de execução pode ser entendido como uma especificação abstrata, uma implementação concreta ou uma instância de corrida. As especificações abstratas usam conjuntos de instruções para especificar o comportamento do mecanismo de execução. Uma implementação específica pode usar uma variedade de tecnologias diferentes - incluindo software, hardware ou uma combinação de tecnologia de árvores. O mecanismo de execução como uma instância de tempo de execução é um thread.
Cada encadeamento de um programa Java em execução é uma instância de um mecanismo independente de execução de máquina virtual. Desde o início ao final do ciclo de vida do encadeamento, ele está executando o bytecode ou executando um método local.
3.1 Conjunto de instruções
O fluxo de bytecode do método é composto por uma sequência de instruções de uma máquina virtual Java. Cada instrução contém um código de opção de byte, seguido de 0 ou mais operandos. O código de opção representa a operação a ser executada; O operando fornece à máquina virtual Java com informações adicionais necessárias para executar o código OPC. Quando uma máquina virtual executa uma instrução, ela pode usar os itens no pool constante atual, os valores na variável local do quadro atual ou os valores na parte superior da pilha de operando do quadro atual.
O mecanismo de execução abstrato executa uma instrução de bytecode por vez. Cada encadeamento (instância do mecanismo de execução) de um programa em execução em uma máquina virtual Java executa esta operação. O mecanismo de execução obtém o código de opção e, se o código OPCODE tiver um operando, ele obterá seu operando. Ele executa a ação especificada pelo código OPCOD e pelo operando a seguir e, em seguida, obtém o próximo código OPC. Esse processo de execução do bytecode continuará até que o thread seja concluído e a conclusão do thread pode ser marcada ao retornar de seu método inicial ou não capturar a exceção lançada.
4 interface de método local
A interface local Java, também chamada JNI (JavanativeInterface), está preparada para a portabilidade. A interface do método local permite que o método local faça o seguinte:
Passar ou retornar dados
Variáveis de instância de operação
Operar variáveis de classe ou métodos de classe de chamada
Array de operando
Bloqueie o objeto Heap
Carregue a nova classe
jogue uma exceção
Pegue a exceção lançada por um método local chamando um método Java
Capture a exceção assíncrona jogada por máquina virtual
Indica que um objeto de coletor de lixo não é mais necessário
Resumir
O exposto acima é tudo sobre este artigo sobre uma compreensão profunda da arquitetura de máquina virtual Java, e espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!