Prezados leitores,

Hoje vou falar de um assunto que acredito que muitos passem, ajustar o GeoServer para que ele possa consumir o mínimo de memória possível e você não ter que passar pelo erro OutOfMemory e correr o risco de deixar sua aplicação indisponível ao usuário.

O Java ele possibilita que você faça a limpeza da memória através do Garbage Collector (GC), e o GC possui alguns algoritmos para te ajudar nesse trabalho.



Eu vou falar nesse post, sobre o Garbage First Garbage Collector (G1GC), que é um algoritmo de coleta de lixo adaptável que se tornou o algoritmo de GC padrão desde o Java 9. Gostaria então de compartilhar algumas dicas para ajustar o coletor de lixo G1 para obter um desempenho ideal. Se você quiser se aprofundar e entender melhor como é o funcionamento do Garbage Collector, basta clicar aqui.

1. Tempo máximo de pausa do GC

Considere passar o argumento ‘-XX:MaxGCPauseMillis’ com sua meta de tempo de pausa preferida. Este argumento define um valor de destino para o tempo máximo de pausa. O algoritmo G1 GC tenta o melhor para atingir esse objetivo.

2. Evite definir o tamanho da geração jovem

Evite definir o tamanho da geração jovem para um tamanho específico (passando os argumentos ‘-Xmn, -XX:NewRatio’). O algoritmo G1 GC modifica o tamanho da geração jovem em tempo de execução para atingir suas metas de tempo de pausa. Se o tamanho da geração jovem for configurado explicitamente, as metas de tempo de pausa não serão alcançadas.

3. Remova argumentos antigos

Quando você estiver migrando de outros algoritmos GC (CMS, Parallel, …) para o algoritmo G1 GC, remova todos os argumentos JVM relacionados ao antigo algoritmo GC. Normalmente, passar argumentos antigos de algoritmos de GC para G1 não terá efeito ou pode até responder de maneira negativa.

4. Eliminando duplicatas de String

Devido a práticas de programação ineficientes, os aplicativos modernos desperdiçam muita memória. Uma das principais razões para o desperdício de memória é a duplicação de string. Um estudo recente indica que 13,5% da memória do aplicativo contém strings duplicadas. G1 GC fornece uma opção para eliminar strings duplicadas quando você passa o argumento ‘-XX:+UseStringDeduplication’. Você pode considerar passar esse argumento para seu aplicativo se estiver executando o Java 8 atualização 20 e superior. Ele tem o potencial de melhorar o desempenho geral do aplicativo. Você pode saber mais sobre essa propriedade neste artigo .

5. Entenda as configurações padrão

Para fins de ajuste, na tabela abaixo, resumimos argumentos importantes do algoritmo G1 GC e seus valores padrão:

-XX:MaxGCPauseMillis=200 – Define um valor máximo de tempo de pausa. O valor padrão é 200 milissegundos.
-XX:G1HeapRegionSize=n – Define o tamanho de uma região G1. O valor deve ser potência de dois, ou seja, 256, 512, 1024,…. Pode variar de 1 MB a 32 MB.
-XX:GCTimeRatio=12 – Define o tempo total de destino que deve ser gasto no GC versus o tempo total a ser gasto no processamento de transações do cliente. A fórmula real para determinar o tempo de GC alvo é [1 / (1 + GCTimeRatio)]. O valor padrão 12 indica que o tempo alvo do GC é [1 / (1 + 12)], ou seja, 7,69%. Isso significa que a JVM pode gastar 7,69% de seu tempo na atividade de GC e os 92,3% restantes devem ser gastos no processamento da atividade do cliente.
-XX:ParallelGCThreads=n – Define o número de threads de trabalho Stop-the-world. Se houver menos ou igual a 8 processadores lógicos, defina o valor de n para o número de processadores lógicos. Digamos que seu servidor tenha 5 processadores lógicos, em seguida, defina n como 5. Se houver mais de oito processadores lógicos, defina o valor de n para aproximadamente 5/8 dos processadores lógicos. Isso funciona na maioria dos casos, exceto para sistemas SPARC maiores, onde o valor de n pode ser aproximadamente 5/16 dos processadores lógicos.
-XX:ConcGCThreads=n – Define o número de linhas de marcação paralelas. Configura n para aproximadamente 1/4 do número de encadeamentos de coleta de lixo paralelo (ParallelGCThreads).
-XX:InitiatingHeapOccupancyPercent=45 – Os ciclos de marcação GC são acionados quando o uso do heap ultrapassa essa porcentagem. O valor padrão é 45%.
-XX:G1NewSizePercent=5 – Define a porcentagem do heap a ser usada como o mínimo para o tamanho da geração jovem. O valor padrão é 5% do heap Java.
-XX:G1MaxNewSizePercent=60 – Define a porcentagem do tamanho do heap a ser usado como o máximo para o tamanho da geração jovem. O valor padrão é 60 por cento de seu heap Java.
-XX:G1OldCSetRegionThresholdPercent=10 – Define um limite superior no número de regiões antigas a serem coletadas durante um ciclo de coleta de lixo misto. O padrão é 10% do heap Java.
-XX:G1ReservePercent=10 – Define a porcentagem de memória de reserva para manter livre. O padrão é 10 por cento. Os coletores de lixo do G1 tentarão manter 10% da pilha para estar sempre livre.

6. Estude as causas do GC

Uma das maneiras eficazes de otimizar o desempenho do G1 GC é estudar as causas que desencadeiam o GC e fornecer soluções para reduzi-las. Aqui estão os passos para estudar as causas do GC.

6.1. Ative o log do GC. Ele pode ser ativado passando os seguintes argumentos da JVM para seu aplicativo durante o tempo de inicialização:

-Xlog:gc*:file={file-path}

{file-path}: é o local onde o arquivo de log do GC será gravado

6.2. Você pode analisar o arquivo de log do GC usando ferramentas gratuitas como GCeasy , Garbage Cat , HP Jmeter . Essas ferramentas relatam os motivos que estão acionando a atividade do GC.



Agora é com você. Espero que tenha gostado do post e que ele tenha sido útil.

Fontes: Oracle, Hoan Nguyen e GCEasy