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

Sua aplicação Java até 60x mais rápida e sem reescrever o código

Sua aplicação Java até 60x mais rápida e sem reescrever o código

Em um mundo com aplicações cada vez mais distribuídas e sem controle de estado, um dos grandes desafios está ligado à performance (seja no tempo de inicialização ou mesmo na resposta à primeira request). Foi dentro deste contexto que durante muito tempo o Java foi uma dúvida em abordagens como serverless, microservices e containers. Mas esses tempos acabaram! Hoje não apenas temos plataformas que levam o Java a um nível de performance jamais imaginado, como também temos algo que possibilita dar um passo além: é a imagem nativa. Venha para esta sessão e aprenda o que dá e o que não dá pra fazer com esta abordagem, e como você pode rodar seu código 60x mais rápido ainda hoje.

Elder Moraes

June 07, 2021
Tweet

More Decks by Elder Moraes

Other Decks in Technology

Transcript

  1. Sua aplicação Java até 60x mais rápida e sem reescrever

    o código Elder Moraes Developer Advocate @elderjava
  2. @elderjava 2 IMAGENS NATIVAS • O que são? • Pra

    que servem? • O que comem? • Posso passar no cabelo?
  3. @elderjava 4 Aviso: esta *não* é uma palestra sobre Graal

    VM! Esta é! https://youtu.be/SivvH93gcco
  4. @elderjava 9 O que é uma imagem nativa? É uma

    tecnologia que utiliza AOT para compilar código Java para um executável standalone
  5. @elderjava 10 Como uma imagem nativa é gerada? • Através

    do Native Image Builder • Ele analisa estaticamente todas as classes e suas dependências
  6. @elderjava 11 Como uma imagem nativa é gerada? • São

    mapeados todos os métodos e bibliotecas envolvidas no runtime • Então ele compila (AOT) todo esse código, gerando um executável nativo para um OS e arquitetura específicos
  7. @elderjava 12 O que está incluído em uma imagem nativa?

    • Classes da aplicação • Classes das dependências • Classes de bibliotecas runtime • Código estático nativo do JDK
  8. @elderjava 14 Eita! Então como funciona? • Imagens nativas possuem

    um sistema de runtime chamado Substrate VM • Alguns dos seus componentes são: gerenciamento de memória, thread scheduling, GC, etc.
  9. @elderjava 16 Limitações Premissas • Todo código de runtime tem

    que ser conhecido em tempo de compilação • Nenhum código novo é carregado em runtime • Como em toda otimização, nem toda aplicação é “otimizável"
  10. @elderjava 17 4 grupos de compatibilidade 1. Features que funcionam,

    mas requerem configuração 2. Features que podem funcionar de modo diferente 3. Features que não funcionam 4. O restante (funciona out of the box) Limitações
  11. @elderjava 18 4 grupos de compatibilidade 1. Features que funcionam,

    mas requerem configuração 2. Features que podem funcionar de modo diferente 3. Features que não funcionam 4. O restante (funciona out of the box) Limitações
  12. @elderjava 20 Dynamic class loading • Ex: Class.forName(“myClass”) • “myClass"

    precisa estar em um arquivo de configuração • Se a classe não estiver disponível, lança ClassNotFoundException 1. Features que funcionam, mas requerem con fi guração
  13. @elderjava 21 Reflection • Classes, métodos e campos acessados via

    reflection precisam ser conhecidos ahead- of-time • O Native Image Builder identificará as chamadas à Reflection API para mapear esses elementos 1. Features que funcionam, mas requerem con fi guração
  14. @elderjava 22 Reflection • Se a análise falhar, os elementos

    acessados via reflection devem ser informados em um arquivo de configuração • Class initializers podem usar reflection sem restrições 1. Features que funcionam, mas requerem con fi guração
  15. @elderjava 23 Dynamic Proxy • É suportado desde que o

    bytecode seja gerado ahead-of-time • Ou seja, a lista de interfaces que definem os proxies precisa ser conhecida em build time 1. Features que funcionam, mas requerem con fi guração
  16. @elderjava 24 Dynamic Proxy • Chamadas mapeadas • java.lang.reflect.Proxy.newProxyInstance •

    java.lang.reflect.Proxy.getProxyClass • Se a análise estática falhar, a lista de interfaces deve ser informada via arquivo de configuração 1. Features que funcionam, mas requerem con fi guração
  17. @elderjava 25 JNI (Java Native Interface) • Muito semelhante ao

    funcionamento do Reflection (acesso objetos, classes, métodos e campos) • Pelo mesmo motivo, os itens acessados devem ser informados via arquivo de configuração 1. Features que funcionam, mas requerem con fi guração
  18. @elderjava 26 JNI (Java Native Interface) • Como alternativa, o

    Native Image possui sua própria interface nativa, bem mais simples que o JNI • Ref: org.graalvm.nativeimage.c 1. Features que funcionam, mas requerem con fi guração
  19. @elderjava 27 Serialização • Os metadados devem ser informados em

    um arquivo de configuração 1. Features que funcionam, mas requerem con fi guração
  20. @elderjava 29 Signal Handlers • Por default, nenhum signal handler

    é registrado em uma imagem nativa • Para ser registrado, o usuário deve fazê-lo explicitamente 2. Features que podem funcionar de modo diferente
  21. @elderjava 30 Signal Handlers • Para registrar, passe a option

    —install- exit-handlers para o Native Image Builder • Esta option dá acesso aos mesmos signal handlers que a JVM daria 2. Features que podem funcionar de modo diferente
  22. @elderjava 31 Class Initializers • Por default, as classes são

    inicializadas no runtime da imagem • Garante compatibilidade, mas limita otimização • Se inicializar em build time, melhora o tempo de startup e pico de performance 2. Features que podem funcionar de modo diferente
  23. @elderjava 32 Class Initializers • Para ajustes (para uma classe,

    uma package ou todas as classes): • --initialize-at-build-time • --initialize-at-run-time 2. Features que podem funcionar de modo diferente
  24. @elderjava 33 Finalizers • Está como deprecated desde o Java

    9 • Implementação complexa para imagens nativas 2. Features que podem funcionar de modo diferente
  25. @elderjava 34 Threads • Métodos do java.lang.Thread que viraram deprecated

    há muito tempo não são implementados em imagens nativas • Ex: Thread.stop() (deprecated desde 1.2) 2. Features que podem funcionar de modo diferente
  26. @elderjava 35 Debug e Monitoramento • Normalmente são feitos através

    de interfaces que assumem a presença do bytecode durante o runtime • O que não ocorre com imagens nativas 2. Features que podem funcionar de modo diferente
  27. @elderjava 36 Debug e Monitoramento • Opção: utilize ferramentas também

    nativas • Ex: GDB (GNU Debugger) e VTune Profiler 2. Features que podem funcionar de modo diferente
  28. @elderjava 38 invokedynamic • O método invocado pode mudar em

    runtime (o que não é possível com imagens nativas) 3. Features que não funcionam
  29. @elderjava 41 Startup mais rápido • Não há classloading (todas

    as classes já foram carregadas, linkadas e inicializadas) • Não há interpretação de código • Não há JIT • Parte da heap já foi gerada na compilação Imagem Nativa vs JVM
  30. @elderjava 42 Menor footprint de memória • Não há metadado

    para as classes carregadas • Não há dados de profiling para otimizações do JIT • Não há cache de código interpretado • Não há estruturas JIT Imagem Nativa vs JVM
  31. @elderjava 45 Não há suporte para: • JVM TI (Java

    Virtual Machine Tool Interface) • Java Agents • JMX (Java Management Extensions) • JFR (Java Flight Recorder) Porque não usar imagens nativas para tudo?
  32. @elderjava 46 Bom apenas para heaps pequenas: • O processo

    de GC é feito pelo SerialGC disponível na SubstrateVM - bem mais limitado que um GC “full” • Se a heap for muito grande, o GC vai degradar a performance da aplicação Porque não usar imagens nativas para tudo?
  33. @elderjava 47 Não há otimização em runtime • Não há

    JIT • Toda a otimização feita na compilação é final Porque não usar imagens nativas para tudo?
  34. @elderjava 48 Não há suporte para head dump e thread

    dump • Ou há… mas apenas na versão Enterprise Porque não usar imagens nativas para tudo?
  35. @elderjava 50 Em aplicações que: • Sejam pequenas • Possam

    ser invocadas múltiplas vezes em curtos períodos de tempo • Possuam um ciclo de vida curto • Ex: CLI apps e serverless functions Quando utilizar imagens nativas?
  36. @elderjava 52 • Todas as otimizações do Quarkus *independem* do

    uso de imagens nativas • Mas, se quiser utilizar, ele é 100% compatível (incluindo suas extensões) • Basta ter o Native Image Builder disponível (via Graal VM ou Mandrel) Quarkus & Imagens Nativas
  37. @elderjava 55 • Fork do Graal VM CE • Em

    linhas gerais: OpenJDK + Native Image Builder • Foco no suporte ao Quarkus • Melhor suporte ao clientes Red Hat • Contribuição para todo o ecossistema Graal VM CE Mandrel & Graal VM