Soy bastante nuevo en el desarrollo de Android y parece que no puedo entender la excepción de Java Out of Memory. Sé que significa que mi aplicación ha superado el presupuesto de VM, pero después de buscar en Google esto muchas veces, todavía no entiendo este concepto. Me temo que mi aplicación utiliza demasiada memoria porque tengo seis selectores de botones por pantalla con dos mapas de bits para cada selector, que son alrededor de 20 kb cada uno de acuerdo con la pestaña de propiedades. En mi rooteado G2x, configuré el presupuesto de VM en 12mb, reinicié mi teléfono y ejecuté mi aplicación sin ningún problema. Estoy desentrañando dibujables en cada onDestroy() y sugiero que el GC también se ejecute aquí. Después de usar la aplicación por un tiempo en el emulador, hago clic en "Causa GC" en mi pantalla DDMS y los resultados son ID = 1, Heap Size 6.133 MB, Asignado 2.895MB, Free 3.238 MB,% Used 47.20, # Objects 52,623.Android Understanding Heap Sizes
Aquí es donde no entiendo lo que está sucediendo, mi emulador está configurado en 24MB de VM. ¿Dónde está ese número? El verdadero problema que tengo es que si configuro el emulador en 16 MB de VM, mi aplicación se bloquea en la segunda actividad con la excepción de Memoria agotada. ¿Cómo es que no se cuelga en mi teléfono con la VM configurada en 12 MB o en mi viejo teléfono HTC Magic con 12 MB de inventario de VM? ¿Ustedes también piensan que mi aplicación está ocupando demasiada memoria? No tengo idea si esos números de DDMS son buenos o no. Gracias por tu tiempo.
En cuanto a mi código, tengo todas las imágenes especificadas en los diseños XML. No realizo ninguna actividad programática con ellas, excepto para agregar oyentes. He encontrado este fragmento de código en aquí y he añadido a todas las actividades que tengo ...
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.myRootLayout));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
Por lo demás todo lo que hago es añadir onClickListeners a los botones que tienen los fondos del png. Me gustaría aprender cómo especificar los fondos de los botones de forma programática, pero necesito que las funciones del selector estén centradas, al presionar, no enfocadas, pero presionadas, etc., para que los fondos de los botones cambien según la interacción del usuario. He revisado los documentos acerca de esto, pero parece abrumador, es por eso que pensé que comenzaría aquí con los conceptos básicos de la administración de Heaps y me abriría camino hasta especificar selectores en el código. Esto puede no tener sentido, pero ¿hay una cantidad "sana" de asignación de memoria que una aplicación podría asignar sin acercarse a la excepción de Memoria agotada? Por ejemplo, si una aplicación asignó 6MB, debería estar bien, pero 8 MB la impulsarían, ¿hay límites como ese en la asignación de memoria? Gracias de nuevo Alex Lockwood por su respuesta Voy a leer y volver a leerlo hasta que esto tenga sentido
+1, respuesta muy informativa! –
¡Muchas gracias! Aprendí mucho de eso. Estoy agregando algo de información al pie de la pregunta –
Comentario de resolución "20 kb cada uno suena bien" - AFAIK, no importa cuál es * el tamaño del archivo * (que será más pequeño para las imágenes que se comprimen mejor), importa lo que * DIMENSIONS * son; en la memoria, para el color completo, tomará 4B por píxel, ¿verdad? Por lo tanto, es importante cambiar el tamaño de la imagen cuando la cargue [documentos de android - Cargue una versión reducida en la memoria], según el tamaño real necesario para el dispositivo actual. – ToolmakerSteve