Tamanhos de Heap Inicial e Máximo

Entender as operações do Coletor de Lixo (GC) ajuda a configurar os tamanhos de heap inicial e máximo para gerenciamento eficiente de heap.

O Coletor de Lixo adapta o tamanho do heap para manter a ocupação entre 40% e 70% pelos seguintes motivos:
  • Uma ocupação de heap superior a 70% aumenta a frequência dos ciclos de coleta de lixo, o que pode reduzir o desempenho. É possível alterar esse comportamento configurando a opção -Xminf.
  • Uma ocupação de heap inferior a 40% significa que os ciclos de coleta de lixo são pouco frequentes. No entanto, esses ciclos são mais longos do que o necessário, causando tempos de pausa mais longos, o que pode reduzir o desempenho. É possível alterar esse comportamento configurando a opção -Xmaxf.
Caso não seja configurado um tamanho de heap inicial ou máximo, o Coletor de Lixo expandirá e reduzirá o heap conforme necessário. No entanto, se você corrigir o tamanho de heap usando as opções -Xms e -Xmx , a GC não expandirá ou reduzirá o heap Java™ Para otimizar o desempenho do aplicativo e permanecer no intervalo de 40% a 70%, a configuração de tamanho de heap máximo deve, então, ser pelo menos 43% maior do que a ocupação máxima do aplicativo. Por exemplo, se um aplicativo tiver uma ocupação máxima de 70 MB, deve-se configurar um tamanho de heap máximo de 100 MB, conforme mostrado no cálculo a seguir:
70 + (70 * 43/100)

A configuração dos tamanhos de heap mínimo e máximo com o mesmo valor geralmente não é uma boa ideia, porque a coleta de lixo será adiada até que o heap esteja cheio. Portanto, a primeira vez que a GC é executada, o processo pode levar mais tempo. Além disso, o heap tem maior probabilidade de estar fragmentado e precisar de uma compactação de heap. Inicie o aplciativo com o tamanho de heap mínimo exigido pelo aplicativo. Quando a coleta de lixo for iniciada, ela será executada de forma frequente e eficiente, porque o heap é pequeno.

Se o GC não puder localizar lixo suficiente, ele executa a compactação. Se o GC localizar lixo suficiente ou qualquer uma das outras condições para a expansão de heap for atendida (consulte Alocação de heap na OpenJ9 documentação do usuário), o GC expandirá o heap.

Portanto, um aplicativo geralmente é executado até o heap estar cheio. Então, ciclos sucessivos de coleta de lixo recuperam o lixo. Quando o heap está cheio de objetos ativos, o GC compacta o heap. Se lixo suficiente ainda não for recuperado, o GC expande o heap.

A partir da descrição anterior, é possível ver que o GC compacta o heap à medida que as necessidades do aplicativo aumentam, de forma que à medida que o heap expande, ele expande com um conjunto de objetos compactados na parte inferior do heap original. Esse processo é uma maneira eficiente de gerenciar o heap, porque a compactação é executada no menor tamanho possível de heap, no momento em que é considerada necessária. A compactação é executada com os tamanhos de heap mínimos à medida que o heap cresce. Existe alguma evidência de que um conjunto de objetos inicial de um aplicativo tem a tendência de ser o conjunto chave ou raiz, de forma que compactá-los anteriormente libera o restante do heap para mais objetos de vida curta.

Eventualmente, a JVM tem o heap no tamanho máximo com todos os objetos de vida longa compactados na partir inferior do heap. A compactação ocorreu quando a compactação estava em sua fase menos cara. As quantidades de processamento e de uso de memória necessárias para expandir o heap é praticamente trivial em comparação ao custo da coleta e compactação de um heap muito grande fragmentado.