java.lang.OutOfMemoryError: se excedió el límite de sobrecarga de GC [duplicado]
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.
Básicamente, te estás quedando sin memoria para ejecutar el proceso sin problemas. Opciones que me vienen a la mente:
- Especifica más memoria como mencionaste, prueba algo intermedio como
-Xmx512m
primero - Trabaje con lotes más pequeños de
HashMap
objetos para procesarlos a la vez si es posible - Si tiene muchas cadenas duplicadas, úselas
String.intern()
antes de colocarlas en elHashMap
- Utilice el
HashMap(int initialCapacity, float loadFactor)
constructor para adaptarlo a su caso.
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"
}
}
@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