Android Entendiendo tamaños de montón

Soy bastante nuevo en el desarrollo de Android y no puedo captar la excepción Java Out of Memory. Sé que significa que mi aplicación ha pasado por el presupuesto de VM, pero después de Google esta vez muchas veces todavía no parecen comprender 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 según la ficha de propiedades. En mi raíz G2x he establecido el presupuesto de VM a 12 MB, reiniciado mi teléfono y corrió mi aplicación sin ningún tipo de problemas. Estoy desatando drawables en cada onDestroy () e insinuando en el GC para funcionar aquí también. Después de usar la aplicación durante un tiempo en el emulador, haga clic en "Causa GC" en mi pantalla DDMS y los resultados son ID = 1, tamaño de montón 6.133 MB, asignado 2.895 MB, 3.238 MB,% utilizado 47.20, # objetos 52.623.

Aquí es donde no entiendo lo que está sucediendo, mi emulador está configurado a 24MB de VM. ¿Dónde está ese número? El problema real que tengo es que si establezco el emulador a 16 MB de VM mi aplicación se bloquea en la segunda actividad con la excepción de memoria perdida. ¿Cómo es que no se bloquea en mi teléfono con la máquina virtual configurada a 12 MB o en mi viejo teléfono HTC Magic con 12 MB de VM? ¿También crees que mi aplicación está tomando demasiada memoria? No tengo idea de si esos números DDMS son buenos o no. Gracias por tu tiempo.

En cuanto a mi código que tengo todas las imágenes especificadas en los diseños XML no hago nada programmaticly con ellos, excepto para añadir oyentes a ellos. He encontrado este pedacito de código aquí y lo he agregado a cada actividad 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(); } } 

De lo contrario todo lo que hago es añadir onClickListeners a los botones que tienen los fondos PNG. Me gustaría aprender a especificar fondos de botón de forma programática, pero tengo que tener las funciones de selector como en el enfoque, en la prensa, no centrado, pero presionado para hacer que el fondo de los botones cambiar de acuerdo a la interacción del usuario. He revisado los documentos acerca de esto, pero parece abrumador, por eso pensé que empezaría aquí con los conceptos básicos de la gestión de Heaps y trabajar mi camino hasta la especificación de selectores en el código. Esto puede no tener sentido pero ¿hay una cantidad "saludable" de asignación de memoria que una aplicación podría asignar sin acercarse a la excepción Fuera de memoria? Por ejemplo, si una aplicación asignada 6MB que debe estar bien, pero 8MB sería empujarlo, hay límites como que 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 para mí

Cuando se establece el presupuesto de VM en su emulador / dispositivo, lo que está haciendo es decirle al montón el tamaño máximo que se permite que sea. En tiempo de ejecución, el montón crece dinámicamente en tamaño como el Dalvik VM solicita memoria del sistema desde el sistema operativo. El Dalvik VM normalmente comienza asignando un montón relativamente pequeño. Luego, después de cada GC ejecutar comprueba para ver cuánta memoria de montón libre hay. Si la proporción entre el montón libre y el montón total es demasiado pequeña, la VM Dalvik agregará más memoria al montón (hasta el tamaño de montón máximo configurado).

Dicho esto, la razón por la que no está viendo "24 mb" en su pantalla DDMS es porque el montón no ha crecido hasta su tamaño máximo. Esto permite a Android hacer un buen uso de la ya pequeña cantidad de memoria que está disponible en dispositivos portátiles.

En cuanto a por qué su aplicación se está estrellando en el emulador y no en su teléfono, que parece extraño (¿está seguro de que los números son correctos?). Debe tener en cuenta, sin embargo, que la memoria se gestiona dinámicamente y que la utilización total de la memoria se determina en función de varios factores externos (la velocidad / frecuencia con la que se realiza la recolección de basura, etc.).

Por último, por las razones que he mencionado anteriormente, sería difícil decir con certeza cómo de bien su aplicación gestiona la memoria basada en la única línea de información que proporcionó anteriormente. Realmente necesitamos ver algo de su código. OutOfMemoryError s definitivamente vale la pena preocuparse, sin embargo, por lo que definitivamente mirar en el uso de la memoria de su aplicación. Una cosa que podría considerar es probar sus imágenes de mapa de bits en tiempo de ejecución con llamadas a inSampleSize utilizando la clase BitmapFactory . Esto puede ayudar a reducir la cantidad de memoria necesaria para cargar los mapas de bits desplegables. O eso o usted podría reducir la resolución de sus drawables (aunque 20 kb cada uno suena bien para mí).

Incluso si su aplicación no alcanza el límite de montón de "24mb" (varía dentro de los dispositivos), es posible que todavía tenga bloqueos porque Android tarda un poco en crecer el espacio de montón para su aplicación.

En mi situación estaba creando y descargando varias imágenes en una pequeña cantidad de tiempo.

Muy a menudo estaba recibiendo OutOfMemoryError .

Parece Android no fue lo suficientemente rápido para crecer el espacio de montón para mi aplicación.

Creo que solucioné este problema usando la configuración de largeHeap en el archivo de manifiesto. Con ese ajuste, Android deja más memoria libre cada vez que crece el montón, minimizando la posibilidad de golpear el límite actual.

No uso el límite de 24mb, pero este conf de gran largeHeap fue muy útil.

Sólo tienes que configurar largeHeap="true" en la etiqueta de la aplicación de tu AndroidManifest.xml

 <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:largeHeap="true" android:theme="@style/AppTheme" > 

Sin embargo, asegúrese de que son cuidadosos cuando se trata de imágenes, como @Alex Lockwood aconsejó.

  • La herramienta Android DDMS se bloquea después de seleccionar un dispositivo
  • Eclipse DDMS no muestra el contenido de la tarjeta SD
  • Filtrar etiquetas en LogCat (en el complemento Android Eclipse)
  • No se puede acceder a la carpeta de datos en el Explorador de archivos de DDMS utilizando un Nexus One!
  • Logcat no puede detectar nombres de aplicaciones o paquetes
  • Enorme byte en mi aplicación después de HPROF
  • ¿Cómo depurar la aplicación firmada de Android de Eclipse?
  • El gestor de archivos del gestor de dispositivos está vacío para emulador de turrones
  • cómo utilizar ddms para fugas de memoria en código c ++
  • Navegar por la base de datos SQLite desde Android Studio
  • Android Black Captura de pantalla en DDMS: ¿Problema? O razón de seguridad?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.