Pregunta Error java.lang.OutOfMemoryError: límite superior de GC excedido


Recibo este mensaje de error mientras ejecuto mis pruebas JUnit:

java.lang.OutOfMemoryError: GC overhead limit exceeded

Sé lo que OutOfMemoryError es, pero ¿qué significa el límite superior de GC? ¿Como puedo resolver esto?


602
2017-09-08 11:34


origen


Respuestas:


Este mensaje significa que, por alguna razón, el recolector de basura tarda demasiado tiempo (de forma predeterminada el 98% de todo el tiempo de CPU del proceso) y recupera muy poca memoria en cada ejecución (por defecto, el 2% del montón).

Esto significa que su programa deja de progresar y está ocupado ejecutando solo la recolección de basura en todo momento.

Para evitar que su aplicación absorba el tiempo de CPU sin hacer nada, la JVM lanza esto Error para que tengas la oportunidad de diagnosticar el problema

Los raros casos en los que he visto que esto sucede es cuando algún código creaba toneladas de objetos temporales y toneladas de objetos con referencias débiles en un entorno que ya estaba muy limitado por la memoria.

Revisa Este artículo para detalles (específicamente esta parte)


614
2017-09-08 11:39



El GC arroja esta excepción cuando se gasta demasiado tiempo en la recolección de basura por muy poco rendimiento, por ej. El 98% del tiempo de CPU se gasta en GC y se recupera menos del 2% del montón.

Esta función está diseñada para evitar que las aplicaciones se ejecuten durante un período de tiempo prolongado sin apenas progreso porque el montón es demasiado pequeño.

Puedes desactivar esto con la opción de línea de comando -XX:-UseGCOverheadLimit

Más información aquí

EDITAR: parece que alguien puede escribir más rápido que yo :)


165
2017-09-08 11:43



Si estás seguro de que no hay pérdidas de memoria en su programa, intente:

  1. Aumente el tamaño del montón, por ejemplo -Xmx1g.
  2. Habilitar el colector de baja pausa concurrente -XX:+UseConcMarkSweepGC.
  3. Reutilice objetos existentes cuando sea posible para guardar algo de memoria.

Si es necesario, el control de límite se puede desactivar agregando la opción -XX:-UseGCOverheadLimit a la línea de comando.


76
2017-12-14 01:44



Usualmente es el código. Aquí hay un ejemplo simple:

import java.util.*;

public class GarbageCollector {

    public static void main(String... args) {

        System.out.printf("Testing...%n");
        List<Double> list = new ArrayList<Double>();
        for (int outer = 0; outer < 10000; outer++) {

            // list = new ArrayList<Double>(10000); // BAD
            // list = new ArrayList<Double>(); // WORSE
            list.clear(); // BETTER

            for (int inner = 0; inner < 10000; inner++) {
                list.add(Math.random());
            }

            if (outer % 1000 == 0) {
                System.out.printf("Outer loop at %d%n", outer);
            }

        }
        System.out.printf("Done.%n");
    }
}

Usando java 1.6.0_24-b07 en un Windows7 de 32 bits.

java -Xloggc: gc.log GarbageCollector

Luego mira gc.log

  • Activado 444 veces con el método BAD
  • Activado 666 veces con el método WORSE
  • Disparo 354 veces con el método BETTER

Ahora bien, esta no es la mejor prueba o el mejor diseño, pero cuando se enfrenta a una situación en la que no tiene más remedio que implementar dicho ciclo o cuando se trata de un código existente que se comporta mal, la elección de reutilizar objetos en lugar de crear nuevos puede reducir la cantidad de veces que el recolector de basura se interpone en el camino ...


34
2018-04-12 19:27



Simplemente aumente un poco el tamaño del almacenamiento dinámico configurando esta opción en

Ejecutar → Ejecutar configuraciones → Argumentos → Argumentos de VM

-Xms1024M -Xmx2048M

Xms - por límite mínimo

Xmx - para el límite máximo


26
2018-05-13 10:40



Causa para el error

Límite de sobrecarga del GC excedido "indica que el recolector de basura se está ejecutando todo el tiempo y el programa Java está avanzando muy lentamente.

Después de una recolección de basura, si el El proceso de Java gasta más de aproximadamente el 98% de su tiempo en la recolección de basura y si está recuperando menos del 2% del montón y ha estado haciendo hasta ahora las últimas 5 colecciones de basura consecutivas (tiempo de compilación), entonces un java.lang.OutOfMemoryError es aventado

  1. Aumenta el tamaño del montón si el montón actual no es suficiente.
  2. Si aún obtiene este error después de aumentar la memoria de montón, use la memoria herramientas de perfilado me gusta ESTERA (Herramienta de análisis de memoria), Visual VM etc. y arreglar fugas de memoria.
  3. Actualice la versión JDK a la última versión (1.8.x) o al menos 1.7.x y use el algoritmo G1GC. . El objetivo de rendimiento para el GC G1 es un 90% de tiempo de aplicación y un 10% de tiempo de recolección de basura
  4. Además de configurar la memoria del montón con -Xms1g -Xmx2g , tratar

    -XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m  
    -XX:ParallelGCThreads=n -XX:ConcGCThreads=n
    

Eche un vistazo a algunas preguntas más relacionadas con G1GC

Colección de basura y documentación de Java 7 (JDK 7) en G1

Colección de basura Java G1 en producción

Artículo de Oracle Technetwork para GC finetuning


23
2018-02-06 18:06



Para mí, los siguientes pasos funcionaron:

  1. Abre el eclipse.ini archivo
  2. Cambio

    -Xms40m
    -Xmx512m
    

    a

    -Xms512m
    -Xmx1024m
    
  3. Reiniciar Eclipse

Mira aquí


12
2017-12-31 05:09