Para configurar os parâmetros da JVM para minimizar as pausas da coleta de lixo (GC), é importante entender as operações fundamentais de diferentes coletores de lixo e os mecanismos de ajuste disponíveis na JVM. O processo de configuração envolve a seleção de um algoritmo apropriado de coleta de lixo, tamanhos de ajuste de ajuste, configuração de tempo de pausa, parâmetros de encadeamento e otimização de regiões de memória. Abaixo está uma síntese detalhada do ajuste da JVM para minimizar pausas GC com base em fontes autoritárias e práticas recomendadas:
escolhendo o coletor de lixo direito
A JVM oferece vários algoritmos de coleta de lixo, cada um com características diferentes sobre a taxa de transferência, os tempos de pausa e o uso de recursos:
- GC serial: usa um único thread para GC. Ele interrompe todos os threads de aplicativos durante a coleta, resultando em pausas longas. Geralmente, não é adequado para minimizar pausas em aplicações maiores.
- GC paralelo: usa vários threads para executar a coleta de lixo, reduzindo os tempos de pausa em comparação com o GC serial, alavancando vários núcleos de CPU. É orientado para o rendimento, mas ainda faz uma pausa nos threads de aplicativos durante o GC.
- GC simultâneo de mark-sweep (CMS): executa grande parte do trabalho de coleta de lixo simultaneamente com a aplicação, reduzindo significativamente os tempos de pausa, pausando apenas brevemente o aplicativo em fases GC específicas. É adequado para aplicações de baixa latência.
- Lixo primeiro (G1) GC: divide a pilha em regiões e concentra -se em coletar regiões com mais lixo primeiro. O objetivo é fornecer tempos de pausa previsíveis e boa taxa de transferência misturando fases simultâneas e paralelas. Muitas vezes, é o padrão nas versões modernas da JVM.
- Shenandoah e ZGC: esses coletores de baixa latência executam todo ou a maioria dos funcionários do GC simultaneamente, visando pausas muito curtas ou quase imperceptíveis, adequadas para grandes pilhas e aplicações altamente responsivas.
A escolha do coletor correto depende dos requisitos de aplicação, como tempo máximo de pausa tolerada, tamanho da pilha e características da carga de trabalho.
Configuração do tamanho da pilha
O tamanho da pilha tem um impacto direto nas durações de frequência e pausa:
-Defina o tamanho da pilha inicial e máxima igual: usando `-xms` e` -xmx` com o mesmo valor, evita o redimensionamento da pilha, o que pode introduzir pausas durante o tempo de execução.
- Tamanho adequado da pilha: A sub-alocação da alocação causa coleções frequentes, aumentando pausas. No entanto, a ampliação leva a ciclos GC mais longos. Encontre um saldo com base nas necessidades de memória do aplicativo.
- Monitore os logs GC e as métricas de uso de heap para ajustar o tamanho da pilha adequadamente.
Controlando o tempo de pausa do GC
A JVM fornece parâmetros para definir metas para o máximo de pausa GC Times:
- `-xx: maxgcpauseMillis =`: define um tempo de pausa máxima de destino em milissegundos para o coletor tentar se cumprir. Embora não seja garantida, a JVM tenta ajustar a taxa de transferência e o trabalho GC para evitar exceder esse tempo de pausa.
- Use este parâmetro com G1 GC ou outros colecionadores que suportam as metas de tempo da pausa para orientar a JVM no balanceamento de rendimento e latência.
Threading and Parallelism
A alavancagem de vários fios durante a coleta de lixo reduz as durações da pausa:
- `-xx: parallelgcthreads =`: define o número de threads usados durante as fases paralelas do GC. Mais fios podem reduzir o tempo de pausa, mas também podem aumentar o uso da CPU.
- `-xx: concGCThreads =`: para colecionadores simultâneos como CMS e G1, define o número de threads que executam fases simultâneas.
- A contagem ideal de encadeamentos deve estar alinhada com o número de núcleos de CPU disponíveis e a carga de trabalho; Os threads de excesso de assinaturas podem degradar o desempenho.
Ajustando tamanhos jovens e antigos de geração
A pilha é normalmente dividida em gerações jovens e idosas. Ajustar seus tamanhos afeta o comportamento do GC:
- Tamanho da geração jovem: a geração jovem maior reduz a frequência de GCs menores, mas aumenta os tempos menores de pausa do GC. Ajuste com base na taxa de alocação de objetos.
- Tamanho da geração antiga: afeta a frequência com que os GCs principais/completos são executados e sua duração.
- O G1 GC divide a pilha em muitas regiões igualmente de tamanho e gerencia o tamanho dinamicamente, mas permite o ajuste dos limiares de iniciação com parâmetros como `-xx: initiatingHeapHeapCupancyPercent`.
Parâmetros específicos do coletor de lixo
Para G1 GC, comumente usado em JVMs modernos:
- `-xx:+useg1gc`: Ativa G1 GC.
- `-xx: maxgcpauseMillis =`: pausa TEMPO DE TEMPO DE PAUSA.
- `-xx: initiatingHeApCupancyPercent =`: inicia a marcação simultânea quando a pilha atinge essa ocupação.
- `-xx:+usestringDuplication`: reduz a pegada de memória desduplicando strings.
- Evite definir explicitamente o tamanho da geração jovem, pois pode interferir nos objetivos do tempo de pausa do G1.
Para CMS GC:
- `-xx:+useConcmarksweepGC`: Ativa o CMS.
-O foco de ajuste na redução de pausas globais para parar o mundo, ajustando o limite de iniciação e a contagem de threads.
Para GC paralelo (orientado para o rendimento):
-`-xx:+useParallelGC` e` -xx:+useParallelOdgc`: Ativa o GC paralelo para gerações jovens e antigas.
- Número de sintonia de threads gc com `-xx: parallelgcthreads`.
redução da taxa de alocação de objetos
Reduzir a taxa na qual novos objetos são criados diminui a pressão do GC:
- perfil e otimize o código para minimizar a criação de objetos desnecessários.
- Use o agrupamento de objetos e reutilize quando possível.
- Ajuste os parâmetros da JVM para regular as regiões de memória interna para obter melhores padrões de alocação de objetos.
Evite chamadas explícitas do GC
- Desativar chamadas GC explícitas do código do aplicativo ou ferramentas externas que podem acionar pausas GC completas usando `-xx:+desabillexplicitGC`.
monitoramento e log
Para entender e ajustar o comportamento do GC, ative o registro GC detalhado:
- Use `-xlog: gc*` em JVMs que suportam o registro unificado (Java 9+).
-No JVMS mais antigo, use `-xx:+printgcdetails -xx:+printgcdatestamps -xloggc:`.
Analise os logs para identificar causas de pausa e sintonizar de acordo.
Recomendações gerais
- Comece a sintonizar com uma lousa limpa removendo argumentos JVM desatualizados.
- Alterações no teste em um ambiente semelhante à produção.
- Use ferramentas como Java Flight Recorder, VisualVM ou Profilers comerciais para coletar dados de uso de GC e uso de memória.
- Etapas de ajuste iterado com base nos tempos de pausa GC observados, taxa de transferência e capacidade de resposta do aplicativo.
Em resumo, a minimização de pausas de coleta de lixo JVM envolve a seleção do coletor de lixo apropriado (de preferência G1, ZGC ou Shenandoah para requisitos de baixa pausa), dimensionando adequadamente as gerações, estabelecendo metas de tempo de pausa, ajustando os fios de concorrência, minimizando a taxa de alocação de objetos, desabilitando GCS explícitos, monitoramento cuidadosos. Os detalhes dependerão da carga de trabalho do aplicativo, tamanho da pilha, versão JVM e características de hardware. Os ajustes devem ser feitos de forma incremental e validados com ferramentas de monitoramento e logs GC detalhados para alcançar o equilíbrio desejado de taxa de transferência e tempo de pausa.
Essa abordagem garante que a coleção de lixo da JVM opere eficientemente com interrupções mínimas no desempenho do aplicativo.