Java.lang.OutOfMemoryError: GC superado el límite de sobrecarga


Estoy recibiendo este error en un programa que crea varios (cientos de miles) objetos HashMap con unas pocas (15-20) entradas de texto cada uno. Todas estas cadenas deben ser recopiladas (sin dividirse en cantidades más pequeñas) antes de ser enviadas a una base de datos.

De acuerdo con Sun, el error ocurre " si se gasta demasiado tiempo en la recolección de basura: si se gasta más del 98% del tiempo total en la recolección de basura y se recupera menos del 2% del montón, un error OutOfMemoryError será lanzado.".

Aparentemente, uno podría usar la línea de comandos para pasar argumentos a la JVM para

  • Aumentar el tamaño del montón, a través de" - Xmx1024m " (o más), o
  • Desactivando la comprobación de errores por completo, a través de "-XX:-UseGCOverheadLimit".

El primer enfoque funciona bien, el segundo termina en otro java.lang.OutOfMemoryError, esta vez sobre el montón.

Entonces, pregunta: ¿hay alguna alternativa programática a esto, para el caso de uso particular (i. e., varios objetos HashMap pequeños)? Si utilizo el método HashMap clear (), por ejemplo, el problema desaparece, ¡pero también lo hacen los datos almacenados en el HashMap! :-)

El problema también se discute en un tema relacionado con en StackOverflow.

Author: Community, 2011-04-30

16 answers

Esencialmente se está quedando sin memoria para ejecutar el proceso sin problemas. Opciones que vienen a la mente:

  1. Especifica más memoria como mencionaste, intenta algo intermedio como -Xmx512m primero
  2. Trabajar con lotes más pequeños de HashMap objetos para procesar a la vez si es posible
  3. Si tiene muchas cadenas duplicadas, use String.intern() en ellos antes de ponerlos en el HashMap
  4. Utilice el HashMap(int initialCapacity, float loadFactor) constructor para ajustar para su caso
 155
Author: WhiteFang34,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-05 06:22:24

Lo siguiente funcionó para mí. Simplemente agregue el siguiente fragmento:

dexOptions {
        javaMaxHeapSize "4g"
}

A su build.gradle:

android {
    compileSdkVersion 23
    buildToolsVersion '23.0.1'

    defaultConfig {
        applicationId "yourpackage"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"

        multiDexEnabled true
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    packagingOptions {

    }

    dexOptions {
        javaMaxHeapSize "4g"
    }
}
 59
Author: Mina Fawzy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-23 14:01:28

@takrl: La configuración predeterminada para esta opción es:

java -XX:+UseConcMarkSweepGC

Lo que significa que esta opción no está activa por defecto. Así que cuando dices que usaste la opción "+XX:UseConcMarkSweepGC" Asumo que estabas usando esta sintaxis:

java -XX:+UseConcMarkSweepGC

Lo que significa que estaba activando explícitamente esta opción. Para la sintaxis correcta y la configuración predeterminada de Java HotSpot VM Options @ this documento

 40
Author: qupera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-17 16:35:25

Para que conste, tuvimos el mismo problema hoy. Lo arreglamos usando esta opción:

-XX:-UseConcMarkSweepGC

Aparentemente, esto modificó la estrategia utilizada para la recolección de basura, lo que hizo que el problema desapareciera.

 23
Author: takrl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-27 16:07:21

Ummm... usted tendrá que:

  1. Reconsidere completamente su algoritmo y estructuras de datos, de modo que no necesite todos estos pequeños HashMaps.

  2. Cree una fachada que le permita colocar esos HashMaps dentro y fuera de la memoria según sea necesario. Un simple caché de LRU podría ser solo el ticket.

  3. Subir la memoria disponible para la JVM. Si es necesario, incluso comprar más RAM podría ser la solución más rápida y barata, si tiene la administración de la máquina que alberga a esta bestia. Dicho esto: Generalmente no soy un fan de las soluciones de" lanzar más hardware", especialmente si se puede pensar en una solución algorítmica alternativa dentro de un plazo razonable. Si usted sigue lanzando más hardware en cada uno de estos problemas que pronto se encuentran con la ley de rendimientos decrecientes.

¿Qué estás tratando de hacer de todos modos? Sospecho que hay un mejor enfoque para su problema real.

 11
Author: corlettk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-27 15:08:37

Use implementación de HashMap alternativa ( Trove). Estándar Java HashMap tiene > 12x sobrecarga de memoria. Se pueden leer detalles aquí.

 9
Author: dir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-17 17:19:25

No almacene toda la estructura en memoria mientras espera llegar al final.

Escriba resultados intermedios en una tabla temporal en la base de datos en lugar de hashmaps - funcionalmente, una tabla de base de datos es el equivalente de un hashmap, es decir, ambos admiten el acceso con llave a los datos, pero la tabla no está vinculada a la memoria, por lo que use una tabla indexada aquí en lugar de los hashmaps.

Si se hace correctamente, su algoritmo ni siquiera debería notar el cambio-correctamente aquí significa usar una clase para representar la tabla, incluso dándole un put(clave, valor) y un get (clave) método al igual que un hashmap.

Cuando la tabla intermedia esté completa, genere la(s) instrucción (s) sql requerida (s) desde ella en lugar de desde la memoria.

 9
Author: Rodney P. Barbati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-28 19:07:28

El colector paralelo lanzará un OutOfMemoryError si se está gastando demasiado tiempo en la recolección de basura. En particular, si se gasta más del 98% del tiempo total en la recolección de basura y se recupera menos del 2% del montón, se lanzará OutOfMemoryError. Esta característica está diseñada para evitar que las aplicaciones se ejecuten durante un período prolongado de tiempo mientras hacen poco o ningún progreso porque el montón es demasiado pequeño. Si es necesario, esta función se puede desactivar añadiendo la opción -XX:-UseGCOverheadLimit al comando alinear.

 8
Author: user3405305,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-25 05:51:42

Si está creando cientos de miles de mapas hash, probablemente esté usando mucho más de lo que realmente necesita; a menos que esté trabajando con archivos o gráficos grandes, almacenar datos simples no debería desbordar el límite de memoria de Java.

Deberías intentar repensar tu algoritmo. En este caso, ofrecería más ayuda sobre ese tema, pero no puedo dar ninguna información hasta que usted proporcione más sobre el contexto del problema.

 5
Author: RétroX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-30 04:04:10

Si tiene java8 , y puede usar el Recolector de basura G1 , ejecute su aplicación con:

 -XX:+UseG1GC -XX:+UseStringDeduplication

Esto le dice al G1 que encuentre Cadenas similares y mantenga solo una de ellas en la memoria, y las otras son solo un puntero a esa cadena en la memoria.

Esto es útil cuando tienes muchas cadenas repetidas. Esta solución puede o no funcionar y depende de cada aplicación.

Más información on:
https://blog.codecentric.de/en/2014/08/string-deduplication-new-feature-java-8-update-20-2/ http://java-performance.info/java-string-deduplication /

 5
Author: George C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-12 14:04:15

Corrija las fugas de memoria en su aplicación con la ayuda de herramientas de perfil como eclipse MAT o VisualVM

Con JDK 1.7.x o versiones posteriores, utilice G1GC, que gasta el 10% en recolección de basura a diferencia del 2% en otros algoritmos de GC.

Aparte de configurar la memoria del montón con -Xms1g -Xmx2g, intente `

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

Echa un vistazo a oracle artículo para ajustar estos parámetros.

Alguna pregunta relacionada con G1GC en SE:

Java 7 (JDK 7) recolección de basura y documentación sobre G1

Recolección de basura Java G1 en producción

Estrategia de recolector de basura agresiva

 3
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:50

En caso de error:

"Error interno del compilador: java.lang.OutOfMemoryError: límite de sobrecarga de GC excedido en java.lang.AbstractStringBuilder "

Aumente el espacio de montón de Java a 2 GB, es decir, -Xmx2g.

 2
Author: bpb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-23 08:17:40

Es necesario aumentar el tamaño de la memoria en Jdeveloper ir a setDomainEnv.cmd.

set WLS_HOME=%WL_HOME%\server
set XMS_SUN_64BIT=256
set XMS_SUN_32BIT=256
set XMX_SUN_64BIT=3072
set XMX_SUN_32BIT=3072
set XMS_JROCKIT_64BIT=256
set XMS_JROCKIT_32BIT=256
set XMX_JROCKIT_64BIT=1024
set XMX_JROCKIT_32BIT=1024

if "%JAVA_VENDOR%"=="Sun" (
    set WLS_MEM_ARGS_64BIT=-Xms256m -Xmx512m
    set WLS_MEM_ARGS_32BIT=-Xms256m -Xmx512m
) else (
    set WLS_MEM_ARGS_64BIT=-Xms512m -Xmx512m
    set WLS_MEM_ARGS_32BIT=-Xms512m -Xmx512m
)
and

set MEM_PERM_SIZE_64BIT=-XX:PermSize=256m
set MEM_PERM_SIZE_32BIT=-XX:PermSize=256m

if "%JAVA_USE_64BIT%"=="true" (
    set MEM_PERM_SIZE=%MEM_PERM_SIZE_64BIT%

) else (
    set MEM_PERM_SIZE=%MEM_PERM_SIZE_32BIT%
)

set MEM_MAX_PERM_SIZE_64BIT=-XX:MaxPermSize=1024m
set MEM_MAX_PERM_SIZE_32BIT=-XX:MaxPermSize=1024m
 2
Author: shashi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-15 07:28:38

Para esto, usa el siguiente código en el archivo de gradle de tu app en el cierre de Android.

Dexopciones { Tamaño de la hoja de Javamax " 4g" }

 2
Author: Abhinandan Chada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-24 09:41:00

Para mi caso aumentar la memoria usando la opción -Xmx fue la solución.

Tuve un archivo 10g leído en Java y cada vez me dio el mismo error. Esto sucedió cuando el valor en la columna RES en el comando top alcanzó la opción value set in-Xmx. Luego, al aumentar la memoria usando la opción -Xmx, todo salió bien.

También hubo otro punto. Cuando establezco JAVA_OPTS o CATALINA_OPTS en mi cuenta de usuario y aumenté la cantidad de memoria nuevamente, obtuve el mismo error. Entonces, yo imprimí el valor de esas variables de entorno en mi código que me dio valores diferentes a los que establecí. La razón fue que Tomcat era la raíz de ese proceso y luego como yo no era un su-doer le pedí al administrador que aumentara la memoria en catalina.sh en Tomcat.

 1
Author: M. Mashaye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-15 18:09:20

Esto me ayudó a deshacerme de este error.Esta opción desactiva - XX: + DisableExplicitGC

 0
Author: kanaparthikiran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-07 16:13:07