java.lang.OutOfMemoryError: se excedió el límite de sobrecarga de GC [duplicado]

Resuelto PNS asked hace 13 años • 16 respuestas

Recibo este error en un programa que crea varios (cientos de miles) objetos HashMap con unas pocas (15-20) entradas de texto cada uno. Estas cadenas deben recopilarse todas (sin dividirlas en cantidades más pequeñas) antes de enviarlas a una base de datos.

Según Sun, el error ocurre "si se dedica demasiado tiempo a la recolección de basura: si se dedica más del 98% del tiempo total a la recolección de basura y se recupera menos del 2% del montón, se generará un OutOfMemoryError. ".

Aparentemente, se podría usar la línea de comando para pasar argumentos a la JVM para

  • Aumentar el tamaño del montón, mediante "-Xmx1024m" (o más), o
  • Deshabilitar la verificació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: ¿existe alguna alternativa programática a esto, para el caso de uso particular (es decir, varios objetos HashMap pequeños)? Si uso el método clear() de HashMap, por ejemplo, el problema desaparece, ¡pero también lo hacen los datos almacenados en HashMap! :-)

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

PNS avatar Apr 30 '11 10:04 PNS
Aceptado

Básicamente, te estás quedando sin memoria para ejecutar el proceso sin problemas. Opciones que me vienen a la mente:

  1. Especifica más memoria como mencionaste, prueba algo intermedio como -Xmx512mprimero
  2. Trabaje con lotes más pequeños de HashMapobjetos para procesarlos a la vez si es posible
  3. Si tiene muchas cadenas duplicadas, úselas String.intern()antes de colocarlas en elHashMap
  4. Utilice el HashMap(int initialCapacity, float loadFactor)constructor para adaptarlo a su caso.
WhiteFang34 avatar Apr 30 '2011 04:04 WhiteFang34

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

dexOptions {
        javaMaxHeapSize "4g"
}

Para usted 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"
    }
}
Mina Fawzy avatar Nov 22 '2015 11:11 Mina Fawzy

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

java -XX:+UseConcMarkSweepGC

es decir, esta opción no está activa por defecto. Entonces, cuando dices que usaste la opción " +XX:UseConcMarkSweepGC", supongo que estabas usando esta sintaxis:

java -XX:+UseConcMarkSweepGC

lo que significa que estabas activando explícitamente esta opción. Para conocer la sintaxis correcta y la configuración predeterminada de Java HotSpot VM Options@ este documento

qupera avatar Feb 03 '2012 09:02 qupera