OutOfMemoryError: Limite de sobrecarga do GC excedido

OutOfMemoryError: Limite de sobrecarga do GC excedido

*1. Visão geral *

Simplificando, a JVM cuida de liberar memória quando os objetos não estão mais sendo usados; esse processo é chamado de Coleta de Lixo (link:/jvm-garbage-collectors [GC]).

O erro GC Overhead Limit Excedido é um da família de java.lang.OutOfMemoryError e é uma indicação de esgotamento de recursos (memória).

Neste artigo rápido, veremos o que causa o erro java.lang.OutOfMemoryError: Limite de sobrecarga da GC excedido e como ele pode ser resolvido.

===* 2. Limite de despesas gerais do GC excedido erro *

OutOfMemoryError é uma subclasse de java.lang.VirtualMachineError; é lançado pela JVM quando encontra um problema relacionado à utilização de recursos. Mais especificamente,* o erro ocorre quando a JVM gasta muito tempo executando a Coleta de Lixo *e só pode recuperar muito pouco espaço de heap.

De acordo com os documentos Java, por padrão, a JVM está configurada para gerar esse erro se o processo Java passar mais de 98% de seu tempo fazendo GC e quando apenas menos de 2% do heap for recuperado em cada execução. Em outras palavras, isso significa que nosso aplicativo esgotou quase toda a memória disponível e o Garbage Collector gastou muito tempo tentando limpá-lo e falhou repetidamente.

Nessa situação, os usuários experimentam extrema lentidão do aplicativo. Certas operações, que geralmente são concluídas em milissegundos, levam mais tempo para serem concluídas. Isso ocorre porque a CPU está usando toda a sua capacidade para a Coleta de Lixo e, portanto, não pode executar outras tarefas.

===* 3. Erro em ação *

Vejamos um pedaço de código que lança java.lang.OutOfMemoryError: Limite de sobrecarga da GC excedido.

Podemos conseguir isso, por exemplo, adicionando pares de valores-chave em um loop não terminado:

public class OutOfMemoryGCLimitExceed {
    public static void addRandomDataToMap() {
        Map<Integer, String> dataMap = new HashMap<>();
        Random r = new Random();
        while (true) {
            dataMap.put(r.nextInt(), String.valueOf(r.nextInt()));
        }
    }
}

Quando esse método é chamado, com os argumentos da JVM como _- Xmx100m -XX: + UseParallelGC (o tamanho do heap Java é definido como 100MB e o algoritmo GC é ParallelGC), obtemos um erro _java.lang.OutOfMemoryError: Limite de sobrecarga excedido da GC. Para entender melhor os diferentes algoritmos de coleta de lixo, consulte o tutorial Basiões da coleta de lixo da Oracle.

Obteremos um erro _java.lang.OutOfMemoryError: Limite de sobrecarga da GC excedido muito rapidamente, executando o comando a seguir na raiz do project :

mvn exec:exec

Também deve ser observado que, em algumas situações, podemos encontrar um erro de espaço de heap antes de encontrar o erro GC Overhead Limit Exceded.

===* 4. Solução de erro de limite superior do GC excedido *

A solução ideal é encontrar o problema subjacente ao aplicativo examinando o código quanto a vazamentos de memória.

As seguintes perguntas precisam ser abordadas:

  • Quais são os objetos no aplicativo que ocupam grandes partes do heap? *Em quais partes do código-fonte esses objetos estão sendo alocados?

Também podemos usar ferramentas gráficas automatizadas, como JConsole, que ajuda a detectar problemas de desempenho no código, incluindo java.lang .OutOfMemoryErrors.

O último recurso seria aumentar o tamanho do heap alterando a configuração de ativação da JVM. Por exemplo, isso fornece 1 GB de espaço de heap para o aplicativo Java:

java -Xmx1024m com.xyz.TheClassName

No entanto, isso não resolverá o problema se houver vazamento de memória no código real do aplicativo. Em vez disso, adiaremos o erro. Portanto, é mais aconselhável reavaliar completamente o uso de memória do aplicativo.

===* 5. Conclusão*

Neste tutorial, examinamos o java.lang.OutOfMemoryError: limite de sobrecarga do GC excedido e os motivos por trás dele.

Como sempre, o código fonte relacionado a este artigo pode ser encontrado over no GitHub.