Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este artigo fornece uma visão geral das estratégias e configurações recomendadas para a conteinerização de aplicativos Java. Ao containerizar uma aplicação Java, considere cuidadosamente quanto tempo de CPU o contentor tem disponível. Depois, considere quanta memória está disponível, tanto em termos de quantidade total de memória como do tamanho do heap da Máquina Virtual Java (JVM). Em ambientes em contêineres, os aplicativos podem ter acesso a todos os processadores e, portanto, ser capazes de executar vários threads em paralelo. É comum, no entanto, que os contêineres tenham uma cota de CPU aplicada que pode limitar o acesso às CPUs.
A JVM utiliza heurísticas para determinar o número de "processadores disponíveis" com base na quota de CPU, o que pode influenciar dramaticamente o desempenho das aplicações Java. A memória alocada para o próprio contêiner e o tamanho da área de heap para a JVM são tão importantes quanto os processadores. Esses fatores determinam o comportamento do coletor de lixo (GC) e o desempenho geral do sistema.
Sugestão
Se não quiseres ajustar estas definições manualmente, o Azure Command Launcher para Java (jaz) aplica automaticamente os valores predefinidos da JVM nativa da cloud para ti. É um substituto direto para o java comando que deteta limites de contentores e seleciona o tamanho do heap e os flags GC que melhor se ajustam. Para mais informações, consulte Ajustar automaticamente a JVM com o Azure Command Launcher para Java.
Contentorizar uma nova aplicação
Ao containerizar uma carga de trabalho Java para uma nova aplicação, considere duas coisas ao pensar na memória:
- A memória alocada para o próprio contêiner.
- A quantidade de memória disponível para o processo Java.
Compreender a ergonomia padrão da JVM
Os aplicativos precisam de um ponto de partida e configurações. A JVM tem ergonomia padrão com valores pré-definidos baseados no número de processadores disponíveis e na quantidade de memória no sistema. A máquina virtual Java (JVM) utiliza os valores predefinidos apresentados nas tabelas seguintes quando é iniciada sem opções ou parâmetros específicos de inicialização.
A tabela seguinte mostra o GC padrão para os recursos disponíveis:
| Recursos disponíveis | GC padrão |
|---|---|
| Qualquer número de processadores Até 1.791 MB de memória |
SerialGC |
| 2+ processadores 1.792 MB ou mais de memória |
G1GC |
A tabela a seguir mostra o tamanho máximo de heap padrão, dependendo da quantidade de memória disponível no ambiente em que a JVM está sendo executada:
| Memória disponível | Tamanho máximo de heap padrão |
|---|---|
| Até 256 MB | 50% de memória disponível |
| 256 MB até 512 MB | ~ 127 MB |
| Mais de 512 MB | 25% de memória disponível |
O tamanho de heap inicial padrão é 1/64 da memória disponível. Esses valores são válidos para OpenJDK 11 e posterior — e para a maioria das distribuições, incluindo Microsoft Build do OpenJDK, Azul Zulu, Eclipse Temurin, Oracle OpenJDK e outros.
Determinar a memória do contêiner
Escolha uma quantidade de memória de contentor que melhor sirva a sua carga de trabalho, dependendo das necessidades da sua aplicação e dos seus padrões de utilização distintos. Por exemplo, se a sua aplicação cria grafos de objetos grandes, provavelmente precisa de mais memória do que precisaria para aplicações com muitos grafos de objeto pequenos.
Sugestão
Se você não sabe quanta memória alocar, um bom ponto de partida é 4 GB.
Determinar a memória de heap da JVM
Ao alocar memória para o heap da JVM, lembre-se de que a JVM precisa de mais memória do que a quantidade alocada para o heap da JVM. Não definas a memória máxima do heap da JVM igual à quantidade de memória do contentor. Esta configuração pode causar erros de falta de memória (OOM) no contentor e falhas do contentor.
Sugestão
Aloque 75% de memória de contêiner para o heap da JVM.
No OpenJDK 11 e posteriores, defina o tamanho do heap da JVM de uma das seguintes formas:
| Descrição | Bandeira | Exemplos |
|---|---|---|
| Valor fixo | -Xmx |
-Xmx4g |
| Valor dinâmico | -XX:MaxRAMPercentage |
-XX:MaxRAMPercentage=75 |
Tamanho mínimo ou inicial do heap
Se o ambiente garante uma determinada quantidade de memória reservada para uma instância da JVM, por exemplo, num contentor, defina o tamanho mínimo do heap ou o tamanho inicial do heap para o mesmo valor que o tamanho máximo do heap. Essa configuração indica à JVM que ela não deve executar a tarefa de liberar memória para o sistema operacional.
Para definir um tamanho mínimo de heap, use -Xms para quantidades absolutas ou -XX:InitialRAMPercentage para quantias percentuais.
Importante
Apesar do que o nome sugere, o flag -XX:MinRAMPercentage define a percentagem máxima padrão de RAM para sistemas com até 256 MB de RAM disponível no sistema.
Determinar qual GC usar
Anteriormente, você determinou a quantidade de memória de heap da JVM inicialmente. O próximo passo é escolher o seu GC. A quantidade máxima de memória heap da JVM disponível condiciona frequentemente a sua escolha de GC. A tabela a seguir descreve as características de cada GC.
| Fatores | SerialGC | ParallelGC | G1GC | ZGC | ShenandoahGC |
|---|---|---|---|---|---|
| Número de núcleos | 1 | 2 | 2 | 2 | 2 |
| Multithread | Não | Sim | Sim | Sim | Sim |
| Tamanho do heap Java | <4 GB | <4 GB | >4 GB | >4 GB | >4 GB |
| Pausa | Sim | Sim | Sim | Sim (<1 ms) | Sim (<10 ms) |
| Sobrecarga | Mínimo | Mínimo | Moderado | Moderado | Moderado |
| Efeito de latência de cauda | Alto | Alto | Alto | Baixo | Moderado |
| Versão JDK | Todos | Todos | JDK 8+ | JDK 17+ | JDK 11+ |
| Melhor para | Pilhas pequenas de núcleo único | Pequenos heaps multicore ou cargas de trabalho em lote com qualquer tamanho de heap | Responsivo em pilhas médias a grandes (interações solicitação-resposta/banco de dados) | Responsivo em pilhas médias a grandes (interações solicitação-resposta/banco de dados) | Responsivo em pilhas médias a grandes (interações solicitação-resposta/banco de dados) |
Sugestão
Para a maioria dos aplicativos de microsserviço de uso geral, comece com o GC paralelo.
Determina quantos núcleos de CPU precisas
Para qualquer GC que não seja o SerialGC, utilize dois ou mais núcleos de vCPU — ou, no Kubernetes, pelo menos 2000m para cpu_limit. Não selecione menos do que um núcleo vCPU em ambientes containerizados.
Sugestão
Se você não sabe com quantos núcleos começar, uma boa escolha são dois núcleos vCPU.
Escolha um ponto de partida
Comece com duas réplicas ou instâncias em ambientes de orquestração de contentores como Kubernetes, OpenShift, Azure Spring Apps, Azure Container Apps e Serviço de Aplicações do Azure. A tabela a seguir resume os pontos de partida recomendados para a conteinerização de seu novo aplicativo Java.
| Núcleos vCPU | Memória do contentor | Tamanho da pilha da JVM | GC | Réplicas |
|---|---|---|---|---|
| 2 | 4 GB | 75% | ParallelGC | 2 |
Use os seguintes parâmetros da JVM:
-XX:+UseParallelGC -XX:MaxRAMPercentage=75
Ajuste automaticamente a JVM com o Azure Command Launcher para Java
As secções anteriores descrevem como escolher manualmente os flags da JVM com base na memória do contentor, núcleos da CPU e tipo de carga de trabalho. Se não quiser manter estas definições por si próprio, o Azure Command Launcher para Java (jaz) aplica automaticamente os valores definidos da JVM nativa na cloud.
O Azure Command Launcher para Java é uma utilitária leve que se coloca entre o comando de arranque e a JVM. Deteta o ambiente da nuvem, incluindo a memória do contentor e os limites da CPU, e, em seguida, seleciona os parâmetros de ajuste mais adequados para o dimensionamento da heap, a seleção do GC e os diagnósticos. Esta abordagem reduz a sobrecarga de configuração e melhora a utilização de recursos logo à partida.
Para usar a ferramenta, substitua o java comando por jaz no seu script de lançamento ou no Dockerfile. Por exemplo, em vez de ajustar manualmente as opções da JVM:
java -XX:+UseParallelGC -XX:MaxRAMPercentage=75 -jar myapp.jar
Utilize jaz:
jaz -jar myapp.jar
A ferramenta está incluída nas imagens do contentor para a Microsoft Build do OpenJDK, pelo que não é necessária qualquer configuração adicional. O seguinte Dockerfile utiliza jaz para executar uma aplicação Java a partir de um ficheiro jar:
# Use any Microsoft Build of OpenJDK base image
FROM mcr.microsoft.com/openjdk/jdk:25-ubuntu
# Add your application.jar
COPY application.jar /application.jar
# Use jaz to launch your Java application
CMD ["jaz", "-jar", "application.jar"]
Para opções de instalação, ambientes suportados e detalhes de configuração, consulte o Azure Command Launcher for Java.
Containerizar uma aplicação local existente
Se a sua aplicação já estiver a correr on-premises ou numa VM na cloud, comece com a seguinte configuração:
- A mesma quantidade de memória que o aplicativo tem acesso atualmente.
- O mesmo número de CPUs ou núcleos vCPU que o aplicativo tem atualmente disponível.
- Os mesmos parâmetros da JVM que você usa atualmente.
Se a combinação de núcleos vCPU ou memória container não estiver disponível, escolha a mais próxima, arredondando os núcleos vCPU e a memória container.
Próximos passos
Agora que compreende as recomendações gerais para a containerização de aplicações Java, continue para os seguintes artigos para estabelecer uma base de containerização e simplificar a afinação da JVM: