Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Arquitetura da JVM e como ela funciona

Arquitetura da JVM e como ela funciona

More Decks by Kamila de fatima santos oliveira

Other Decks in Programming

Transcript

  1. Quem sou eu Backend Developer na Ame Digital Microsoft MVP

    em Developer Technologies Book co-author Community organizer
  2. Agenda 1. O que é a JVM 2. Como ela

    funciona 3. Class Loader 4. JVM Memory 5. Method area 6. Heap 7. JVM Language stacks
  3. Agenda 8. PC Registers 9. Native Method stacks 10. Execution

    Engine 11. Interpreter 12. Just in Time Compiler
  4. Agenda 13. Garbage Collector 14. Native Method Interfaces 15. Native

    Method Libraries 16. Java Compilation and execution
  5. O que é a JVM? Jvm é o core do

    ecossistema Java e faz com que os aplicativos baseados em Java (outras linguagens que também usam o JVM) sigam a frase "escreva uma vez, execute em qualquer lugar". Com a JVM, o código escrito em uma máquina pode ser executado em outra que usa a JVM.
  6. Como é seu funcionamento? -> O código Java é compilado

    em bytecode. -> é interpretado em máquinas diferentes -> Bytecode é uma linguagem intermediária entre o sistema host e o código-fonte Java.
  7. Class Loader Quando você compila um arquivo java, ele é

    convertido em bytecode (arquivo .class). Quando você tenta usar esta classe em seu aplicativo, o class loader o carrega na memória principal.
  8. Class Loader - Loading Normalmente, a primeira classe a ser

    carregada na memória é a classe principal (que contém o método principal). Jvm armazena as seguintes informações no method area:
  9. Class Loader - Loading 1. O nome da classe carregada

    e sua classe pai. 2. Todos os arquivos .class relacionados a esta classe 3. Modificadores, Métodos e Variáveis. Temos 3 carregadores de classes integrados disponíveis em Java:
  10. Class Loader - Loading Bootstrap class loader: O carregador de

    classes raiz. É a superclasse do Extension Class Loader e carrega os pacotes Java padrão (lang, util, net, io ..). Esses pacotes padrão estão presentes no arquivo rt.jar e em outras bibliotecas centrais no diretório $ JAVA_HOME / jre / lib.
  11. Class Loader - Loading Extension Class Loader: é a subclasse

    do Bootstrap Class Loader e a superclasse do Application Class Loader. Carrega as extensões das bibliotecas Java padrão presentes no diretório $ JAVA_HOME / jre / lib / ext
  12. Class Loader - Loading Application Class Loader: O último class

    loader e a subclasse do Extension Class Loader. Carrega os arquivos presentes no caminho de classe. O caminho de classe é definido como o diretório atual do aplicativo.
  13. Class Loader - Loading A JVM usa o método ClassLoader.loadClass

    () para carregar a classe na memória. Tenta carregar a classe com base em um nome totalmente qualificado.
  14. Class Loader - Loading Se um class loader pai não

    puder localizar uma classe, delega o trabalho a um class loader filho. Se o filho não for capaz de carregar a classe, ele lança noClassDefFoundError ou ClassNotFoundException.
  15. Class Loader - Linking Depois que uma classe é carregada

    na memória, ela vai para o processo de linking . O processo de linking envolve combinar os diferentes elementos e dependências do programa.
  16. Class Loader - Linking Linking inclui as seguintes etapas: 1.

    Verificação 2. Preparação 3. Resolução
  17. Class Loader - Linking Verificação: Verifica se um arquivo está

    corretamente formatado e se foi gerado por compilador válido ou não. Se essa verificação falhar, nós recebemos uma runtime exception java.lang.VerifyError. Essa verificação é feita pelo componente ByteCodeVerifier. Quando essa atividade é concluída a classe está pronta para compilação.
  18. Class Loader - Linking Preparação: JVM aloca memória para variáveis

    de classe e inicializa a memória para valores padrão.
  19. Class Loader - Linking Resolução: O processo de substituição de

    referências simbólicas, o processo é feito pesquisando no method area para alocar a entidade de referência.
  20. Class Loader - Initialization Nesta etapa, todas as variáveis estáticas

    são atribuídas com seus valores definidos no código e no bloco estático. Esta etapa é executada de cima para baixo em uma classe de pai para filho na hierarquia de classes.
  21. JVM Memory Nós temos 5 componentes nessa area: • Method

    area • Heap • JVM language stacks • PC registers • Native Method stacks
  22. JVM Memory - Method Area Todos os dados de nível

    de classe como o pool de constantes de tempo de execução, , dados de método e código para métodos e construtores são armazenados nesta área.
  23. JVM Memory - Method Area Se a memória disponível nesta

    área não for suficiente para a inicialização do aplicativo, a JVM lança um OutOfMemoryError.
  24. JVM Memory - Method Area Existe apenas uma área de

    método por JVM e é um recurso compartilhado.
  25. JVM Memory - Heap Area Aqui estão todos os objetos,

    suas variáveis de instância e matrizes relacionadas. Esta memória é compartilhada por vários threads.
  26. JVM Memory - JVM language Stacks Quando uma nova thread

    é criada na JVM, uma pilha de tempo de execução separada também é criada neste momento.
  27. JVM Memory - JVM language Stacks Variáveis locais, chamadas de

    método e resultados parciais são armazenados aqui.
  28. JVM Memory - JVM language Stacks Um stackOverFlowError ocorre quando

    um processo que está sendo executado em uma thread requer um tamanho de pilha muito grande que não está disponível.
  29. JVM Memory - JVM language Stacks Para cada chamada de

    método, uma entrada é feita na pilha de memória (stack frame) quando essa chamada de método é concluída, a stack frame é destruído.
  30. JVM Memory - JVM language Stacks A stack frame é

    dividida em 3 partes: • Local Variables • Operand stack • Frame Data
  31. JVM Memory - JVM language Stacks • Local Variables: cada

    frame contém um array de variáveis chamado local variables. Todas local variables e seus valores são armazenados aqui. No tempo de compilação o tamanho desse array é determinado.
  32. JVM Memory - JVM language Stacks • Operand stack: Cada

    frame contém uma pilha LIFO chamada operand stack. Atua como um workspace em tempo de execução para performar operações intermediárias.
  33. JVM Memory - JVM language Stacks • Frame Data: Armazena

    todos os símbolos correspondentes ao method area e armazena as informações do bloco catch em caso de exceptions.
  34. PC (Program Counter) Registers Cada thread tem o seu próprio

    PC registers para armazenar o endereço do que está sendo executado no momento na JVM.
  35. JVM Memory - PC (Program Counter) Registers Quando a instrução

    é executada, o PC register é atualizado com a próxima instrução.
  36. JVM Memory - Native Method Stacks Para cada nova thread,

    uma nova native method stack é alocada.
  37. Execution Engine Na execution engine nós temos 3 partes: •

    Interpreter • Just-In-Time Compiler(JIT) • Garbage Collector
  38. Execution Engine • A execution engine executa os bytecodes (arquivo

    .class) • Lê o bytecode linha a linha • Então usa os dados e informação presentes na área de memória para executar instruções.
  39. Execution Engine - Interpreter O interpreter é responsável por ler

    e executar o bytecode linha a linha. Devido a esse processo linha a linha o interpreter é uma das etapas mais demoradas.
  40. Execution Engine - Interpreter Quando um método é chamado múltiplas

    vezes,a cada vez é necessário uma nova interpretação.
  41. Execution Engine - JIT Compiler Nessa etapa, os pontos negativos

    de demora do interpreter são “compensados”. Porque, a execution engine primeiro usa o interpreter para executar o bytecode e quando acha algum código repetido, usa o JIT compiler.
  42. Execution Engine - JIT Compiler JIT compila todo o bytecode

    e converte para código de imagem nativa. Então, esse código nativo é usado para repetir chamada de métodos, que melhora a performance.
  43. Execution Engine - JIT Compiler JIT tem 4 componentes: •

    Intermediate Code Generator • Code Optimizer • Target Code Generator • Profiler
  44. Execution Engine - JIT Compiler O intermediate code generator é

    responsável por gerar o código intermediário
  45. Execution Engine - JIT Compiler O code optimizer é responsável

    por otimizar o código para uma performance melhor.
  46. Execution Engine - JIT Compiler O target code generator é

    responsável por converter código intermediário para código de máquina nativo.
  47. Execution Engine - JIT Compiler Profiler é responsável por encontrar

    os hotspots (uma das tecnologias que a JVM utiliza para detectar pontos quentes da sua aplicação: código que é executado muito)
  48. Execution Engine - Garbage Collector O Garbage Collector (GC) é

    responsável por coletar e remover objetos não referenciados do heap. Esse processo recupera a memória de tempo de execução automaticamente destruindo eles.
  49. Execution Engine - Garbage Collector Esse processo tem 2 etapas:

    • Mark: O GC identifica os objetos não utilizados na memória. • Sweep: O GC remove os objetos identificados no passo anterior.
  50. Execution Engine - Garbage Collector GC é executado automaticamente pela

    JVM em intervalos regulares mas também pode ser disparado chamando System.gc ()
  51. Execution Engine - Garbage Collector Nós temos 3 tipos de

    GC: • Serial GC • Parallel GC • Garbage First (G1) GC
  52. Execution Engine - Garbage Collector Serial GC: é destinado para

    aplicações pequenas que executam em ambiente single-thread,é a implementação mais simples do GC. O argumento da JVM para usar o Serial Garbage Collector é -XX:+UseSerialGC
  53. Execution Engine - Garbage Collector Parallel GC: é o tipo

    default de GC da JVM. Usa múltiplas threads para garbage collection, mas permanece pausado quando a aplicação está em execução. O argumento da JVM para usar o Parallel Garbage Collector é -XX:+UseParallelGC.
  54. Execution Engine - Garbage Collector Garbage First (G1): recomendado para

    aplicações multi-thread que tem grande espaço de heap disponível.A heap é dividida em espaços de tamanho iguais, G1 identifica as regiões com maior “lixo” e faz a coleta nessa região primeiro.
  55. Execution Engine - Garbage Collector O argumento da JVM para

    usar o G1 Garbage Collector é -XX:+UseG1GC
  56. Native Method Interfaces É uma interface (como uma ponte) Que

    interage com as Native Method Libraries e provem as native libraries (C, C++).
  57. Native Method Interfaces Isso permite que a JVM chame bibliotecas

    C/C++ e seja chamada por bibliotecas C/C++
  58. Native Method Interfaces Usando a palavra chave native você pode

    indicar que aquela implementação de método foi provida por uma biblioteca nativa, você precisa invocar o método System.loadLibrary() para carregar essa biblioteca nativa compartilhada na memória ,e torna essas funções disponíveis em Java.
  59. Native Method Libraries São bibliotecas que são escritas em outras

    linguagens de programação (como assembly, C e C++). Essas bibliotecas geralmente estão presentes na forma de arquivos .dll ou .so.
  60. • Na classe main temos dois métodos f1 e f2

    • O método main estaria na classe 1 • O método f1 é armazenado no arquivo a2.java • O método f2 é armazenado no arquivo a2.java
  61. • O compilador vai compilar esses três arquivos e produzir

    3 arquivos correspondentes .class que consistem em arquivos de bytecode.
  62. • A JVM reside na memória RAM da nossa máquina,

    durante a execução, utilizando o class loader os arquivos são trazidos para a memória RAM
  63. • Na última etapa, a execution engine converte o bytecode

    para código de máquina nativo, isso em tempo de execução.
  64. Por que Java é linguagem interpretada e compilada? Um compilador

    é um programa que converte um programa de um nível de linguagem para outro.
  65. Por que Java é linguagem interpretada e compilada? O nosso

    compilador java converte o código java de alto nível em bytecode (que é código de máquina)
  66. Por que Java é linguagem interpretada e compilada? Já um

    intérprete é um programa que converte um programa de um nível para outra linguagem de programação do mesmo nível. Por exemplo: conversão de programa Java em C ++
  67. Por que Java é linguagem interpretada e compilada? No Java,

    o Just In Time Code generator converte esse bytecode em código de máquina nativo que está nos mesmos níveis de programação.