Observação:
- Este tutorial está disponível em um ambiente de laboratório gratuito fornecido pela Oracle.
- Ele usa valores de exemplo para credenciais, tenancy e compartimentos do Oracle Cloud Infrastructure. Ao concluir seu laboratório, substitua esses valores por valores específicos do seu ambiente de nuvem.
Otimize Aplicativos Java Nativos da Nuvem com GraalVM PGO Empresarial
Introdução
Este laboratório mostra como executar um benchmark Java Microbenchmark Harness (JMH) como um executável nativo, criado com o GraalVM Native Image e aplicar o Profile-Guided Optimization (PGO) para melhorar o desempenho.
GraalVM Native Image permite que você compile um aplicativo Java em um executável nativo que começa quase que instantaneamente, requer menos memória e CPU.
A Otimização Guiada por Perfil (PGO) é uma técnica comumente usada no ecossistema Java para mitigar a otimização just-in-time ausente e reunir os perfis de execução em uma execução e, em seguida, usá-los para otimizar a(s) compilação(ões) subsequente(s). Com a PGO, você pode coletar os dados de criação de perfil e, em seguida, alimentá-los para a ferramenta native-image
, que usará essas informações para otimizar ainda mais o desempenho do executável resultante.
Observações sobre o Uso do JMH com a Imagem Nativa GraalVM
Ao executar na JVM, o JMH forçará uma nova JVM para cada benchmark para garantir que não haja interferência nas medições de cada benchmark. Essa abordagem não é possível ao usar o GraalVM Native Image; portanto, você deve considerar a seguinte orientação ao criar benchmarks do JMH que devem ser executados como executáveis nativos:
- Incluir um único benchmark em cada executável nativo
- Anote o benchmark com
@Fork(0)
para garantir que ele não seja falsificado- Se você quiser criar um perfil do benchmark para gerar um benchmark otimizado, obviamente, ignore os resultados do benchmark durante a criação do perfil
Observação: O OCI (Oracle Cloud Infrastructure) fornece GraalVM Enterprise sem custo adicional.
Objetivos do laboratório
Neste laboratório, você irá:
- Conecte-se a um host remoto no Oracle Cloud
- Compilar e executar um benchmark JMH na JVM
- Crie este benchmark JMH em um executável nativo usando GraalVM Native Image e execute-o
- Otimize a versão executável nativa com o PGO e execute-a
Tempo estimado do laboratório: 30-45 minutos
OBSERVAÇÃO: se você vir o ícone de laptop nas instruções, isso significa que é necessário informar um comando. Fique de olho por isso.
# This is where we you will need to do something
Para copiar um comando, passe o mouse sobre o campo e clique no ícone Copiar para área de transferência.
Para colar um comando copiado em uma janela de terminal, clique com o botão direito do mouse e selecione a opção Colar no menu de contexto. Se preferir atalhos de teclado, use CTRL+SHIFT+V
.
ETAPA 1: Estabelecer Conexão com um Host Remoto e Verificar o Ambiente de Desenvolvimento
Seu ambiente de desenvolvimento é fornecido por um host remoto: uma Instância de Computação do OCI com Oracle Linux 8, 4 CPUs e 32 GB de memória.
O ambiente de área de trabalho será exibido antes que o host remoto esteja pronto, o que pode levar até dois minutos.
O Visual Studio Code (VS Code) será aberto e se conectará automaticamente à instância da VM que foi provisionada para você. Clique em Continuar para aceitar a impressão digital da máquina.
Se você não clicar em Continuar, o VS Code exibirá uma caixa de diálogo, mostrada abaixo. Clique em Repetir. O VS Code pedirá que você aceite impressão digital da máquina. Clique em Continuar.
Problemas com a Conexão com o Ambiente de Desenvolvimento Remoto
Se você encontrar outros problemas nos quais o VS Code falha ao estabelecer conexão com o ambiente de desenvolvimento remoto que não são abordados acima, tente o seguinte:
- Fechar Código VS
- Clique duas vezes no ícone "Luna-Lab.html" na sua área de trabalho
- Copie o "Configurar Script" da guia Recursos e cole-o no Terminal de Desktop do Luna novamente
- Repita as instruções acima para se conectar ao ambiente de desenvolvimento remoto
Parabéns, agora você está conectado a um host remoto no Oracle Cloud!
O script abrirá o VS Code, conectado ao seu host remoto, com o código-fonte do laboratório aberto.
Em seguida, abra um Terminal no VS Code. O Terminal permite que você interaja com o host remoto. Um terminal pode ser aberto no VS Code por meio do menu: Terminal > Novo Terminal, conforme mostrado abaixo.
Observação sobre o Ambiente de Desenvolvimento
Você usará o GraalVM Enterprise como um ambiente de runtime Java para este laboratório. GraalVM é uma distribuição JDK de alto desempenho da Oracle criada no Oracle Java SE.
Seu ambiente de desenvolvimento vem pré-configurado com o GraalVM Enterprise e o conjunto de ferramentas Native Image necessários para este laboratório. Você pode verificar isso executando estes comandos no terminal:
java -version
native-image --version
Você pode prosseguir para a próxima etapa.
ETAPA 2: Compilar e Executar um Benchmark JMH na JVM
O código-fonte do aplicativo - benchmark JMH - está disponível no seu host remoto. O benchmark JMH se origina do Jogo de Benchmarks do Compute Language. Ele cria árvores binárias - antes de qualquer nó de árvore ser coletado lixo - usando no mínimo o número de alocações.
Este benchmark JMH usa a reflexão de Java. A ferramenta native-image
opera sob o que é conhecido como a suposição "mundo fechado" e não incluirá elementos acessados refletivamente no executável nativo, a menos que a ferramenta seja fornecida com a configuração necessária no tempo de construção. Para criar um executável nativo deste benchmark JMH, você precisa executar o Agente de Rastreamento para fornecer a configuração de reflexão para native-image
. Isso já foi feito para você economizar tempo e a configuração gerada pode ser encontrada em src/main/resources/META-INF/native-image/. Para obter mais informações sobre a configuração de reflexão, consulte Luna Lab sobre GraalVM Native Image and Reflection.
Crie e execute o benchmark como um aplicativo Java, executando o seguinte comando:
mvn clean package exec:exec
Observe que no arquivo pom.xml há instruções para desativar explicitamente o compilador JIT GraalVM usando a opção -XX:-UseJVMCICompiler
. Isso significa que o benchmark será executado usando o compilador JIT C2.
O aplicativo executará o benchmark em três iterações e exibirá os resultados no terminal. A execução deve levar menos de quatro minutos para ser concluída. O resultado final é o mais significativo. Você deverá ver algo como:
Benchmark (binaryTreesN) Mode Cnt Score Error Units
BinaryTrees.bench 14 thrpt 3 180.819 ± 8.301 ops/s
Agora você pode passar para a próxima etapa.
ETAPA 3: Criar e Executar um Benchmark JMH como um Executável Nativo
Agora crie um executável nativo usando o GraalVM Enterprise Native Image.
O benchmark JMH é criado com o Maven e aplica o plug-in Maven para criação de Imagens Nativas GraalVM (abra pom.xml para ver o registro do plug-in native-maven-plugin
). O plug-in indica qual arquivo JAR ele precisa passar para native-image
e qual deve ser a classe principal executável.
-
Crie um executável nativo. O build deve levar aproximadamente um minuto:
mvn package -Pnative
O perfil Maven
-Pnative
ativa a criação de um executável nativo. Ele gerará um executável nativo no diretório target, chamadobenchmark-binary-tree
. -
Em seguida, execute o benchmark como um executável nativo:
./target/benchmark-binary-tree
Estes são os resultados obtidos com o GraalVM Enterprise Native Image 22.2.0:
Benchmark (binaryTreesN) Mode Cnt Score Error Units BinaryTrees.bench 14 thrpt 3 174.135 ± 10.020 ops/s
Os números executáveis nativos podem ser semelhantes ou melhores em comparação com a opção anterior (não nativa). Os resultados variarão, dependendo do hardware no qual você executar o mesmo benchmark.
Agora você pode passar para a próxima etapa.
ETAPA 4: Otimizar um Executável Nativo com PGO e Executar
Agora otimize seu executável nativo usando GOP (Profile-Guided Optimization). É um processo de duas etapas. Primeiro, crie uma versão instrumentada do executável nativo e execute-a para rastrear sua execução e coletar um perfil de desempenho. Quando a execução terminar, ela gerará um arquivo de perfil, default.iprof, no diretório raiz do projeto. Em seguida, crie um executável otimizado contendo os dados de perfil sobre o benchmark e execute-o.
O recurso de Otimização Guiada por Perfil (PGO) está disponível com o GraalVM Enterprise Edition.
-
Crie um executável nativo instrumentado informando o perfil
-Pinstrumented
do Maven:mvn package -Pinstrumented
Ele gera um binário no diretório de destino, chamado
benchmark-binary-tree-instr
. -
Execute-a para coletar os perfis de frequência de execução de código:
./target/benchmark-binary-tree-instr
Os perfis coletados dessa execução são armazenados no arquivo default.iprof no diretório de trabalho atual, se nada mais for especificado.
Observação: Você pode especificar onde coletar os perfis ao executar um executável nativo instrumentado informando a opção
-XX:ProfilesDumpFile=YourFileName
no runtime. Você também pode coletar vários arquivos de perfil especificando nomes diferentes e transmiti-los para a ferramentanative-image
no momento da criação. -
Agora que você gerou o arquivo de perfil, crie a versão otimizada:
mvn package -Poptimized
Ele gera um binário otimizado no diretório
target
, chamadobenchmark-binary-tree-opt
. -
Por fim, execute o executável nativo otimizado:
./target/benchmark-binary-tree-opt
Estes são os resultados obtidos com o GraalVM Enterprise Native Image 22.2.0 na máquina host:
Benchmark (binaryTreesN) Mode Cnt Score Error Units
BinaryTrees.bench 14 thrpt 3 223.241 ± 3.578 ops/s
A pontuação média de operações por segundo aumentou de 180 em execução como um aplicativo Java para 223 em execução como um executável nativo otimizado. Os resultados variarão, dependendo do hardware no qual você executar o mesmo benchmark.
Resumo
Este laboratório mostrou como você pode otimizar executáveis nativos com a Otimização Guiada por Perfil (PGO) para obter maior throughput em comparação com a versão Java, preservando ainda outros benefícios: inicialização instantânea, menor uso de CPU e memória. Com o PGO, você pode "treinar" seu aplicativo para cargas de trabalho específicas e transformá-lo em um binário otimizado sem sacrificar nenhum desempenho.
Saiba Mais
Parabéns! Você concluiu com sucesso este laboratório.
Mais Recursos de Aprendizagem
Explore outros laboratórios no site docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal YouTube do Oracle Learning. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.
Para obter a documentação do produto, visite o Oracle Help Center.
Optimize Cloud Native Java Applications with GraalVM Enterprise PGO
F75977-01
January 2023
Copyright © 2023, Oracle and/or its affiliates.