PDA

Ver la Versión Completa : Outofmemory bitmap exceeds vm


reduv
30/05/12, 19:47:45
Hola a todos, soy nuevo programando en Android y quería comentaros un problema que estoy teniendo. Estoy haciendo una aplicación muy simple con un menú principal y dos opciones, en una de ellas cargo un mapa con la API de Google Maps y en otra meto una serie de botones y fotos y texto. Aquí llega el problema, cuando cargo el mapa y doy para atrás y pincho en la otra opción (la de las fotos, texto y video) rompe la aplicación por este error "Outofmemory bitmap exceeds vm", pero si doy al mapa, salgo de la aplicación y doy a la otra opción entra perfectamente, por eso deduzco que al cargar el mapa, el sistema se queda sin la memoria suficiente para abrir la otra opción. He estado intentando cerrar la activity del mapa con el botón de atrás para liberar memoria y poder entrar en la otra opción pero no se me cierra, se me queda cargado en la memoria. He probado con los métodos finish(), ondestroy() pero nada, no cierra la actividad del mapa. ¿Cómo lo podría hacer? Gracias de antemano. :pensando:

reduv
30/05/12, 19:49:49
Tampoco puedo reducir las imágenes porque pierdo mucha calidad en dispositivos de mayor resolución. Estoy algo desesperado, espero que me ayuden, gracias :rolleyes:

kriogeN
30/05/12, 20:46:14
Para solucionar el problema puedes hacerlo de 2 formas, la primera es la que leerás en todos sitios si buscas por Internet, pero yo para resolverlo uso la 2ª opción.

1) Usar Recycle sobre todos los Bitmap cada vez que vayas a dejar de usarlos, en tu caso, en el OnDestroy. Con esto liberas la memoria que dejan los Bitmap justo al ejecutar la función, sin esperar a que el recolector de basura pase.

2) Introducir el Bitmap dentro de un SoftReference cuando lo creas, y luego al asignar el Bitmap asignas el Get del SoftReference. Con esto cuando el sistema necesite memoria lo primero que va a eliminar son los Bitmap, casi todos los problemas que he tenido yo como el que te ocurre a ti lo he solucionado así.

Para tu caso cualquiera de los 2 métodos te vale, pero la ventaja del 2º es que también vale para casos en los que no sabes cuando tienes que liberar la memoria, por ejemplo, imagina que tienes un ListView con 1000 items y que cada item es una imagen, y los vas cargando conforme scrolleas. Si usas el método 1, no sabrás cuando hacer el Recycle, así que cuando lleves scrolleados unos cuantos items te dará el error. En cambio con el método 2 conforme scrolleas irá eliminando las imagenes que tenías por encima (porque al no ser visibles el sistema piensa que ya no las necesita, y al ser SoftReferences es lo primero que elimina), y si vuelves a subir las tendrá que volver a cargar, pero por lo menos no te dará error.

mocelet
30/05/12, 21:49:45
:dios: Lo que aprende uno... X-D en su día lo resolví a base de recycles, efectivamente tienes que tener cuidado con cuándo lo reciclas vaya que le dé por pintarse y no pueda. La idea del SoftReference me parece genial, ¡gracias por compartirla!

reduv
30/05/12, 21:59:28
Muchas gracias por tu respuesta, pero no tengo idea de usar los bitmaps, yo lo que tengo son varios imageviews y textviews en una opcion del menu y luego el mapa en la otra. ¿Cómo se usan los bitmap? ¿Hay que pasar las imageviews a bitmaps o como? Siento mi torpeza pero soy novato en programacion. ¿Me podrías explicar un poco lo de los bitmap o pasarme algun tutorial? Gracias de antemano

kriogeN
30/05/12, 22:04:54
:dios: Lo que aprende uno... X-D en su día lo resolví a base de recycles, efectivamente tienes que tener cuidado con cuándo lo reciclas vaya que le dé por pintarse y no pueda. La idea del SoftReference me parece genial, ¡gracias por compartirla!

De nada :risitas:, en que en día tuve que hacer lo que he puesto arriba, era una aplicación tipo Twitter, que aparece una imagen y luego un texto en un ListView, y no sabía como hacer para poner el Recycle. Se me ocurrió probar con SoftReferences y funcionó perfectamente.

Una cosa a tener en cuenta es que al trabajar con SoftReferences tienes que hacer 2 chequeos de NULL antes de asignar el Bitmap. El primero el del propio SoftReference, y el 2º el Get del SoftReference (que es el Bitmap).

kriogeN
30/05/12, 22:07:03
Muchas gracias por tu respuesta, pero no tengo idea de usar los bitmaps, yo lo que tengo son varios imageviews y textviews en una opcion del menu y luego el mapa en la otra. ¿Cómo se usan los bitmap? ¿Hay que pasar las imageviews a bitmaps o como? Siento mi torpeza pero soy novato en programacion. ¿Me podrías explicar un poco lo de los bitmap o pasarme algun tutorial? Gracias de antemano

¿El fallo te lo está dando con Drawables? Algo debes estar haciendo mal, o en algún momento del código conviertes (aunque sea de forma implicita) el Drawable en un Bitmap. Porque trabajando con Drawables no deberías tener problemas.

¿Puedes poner el código que usas para asignar las imagenes al ImageView?

reduv
30/05/12, 22:27:40
Hola, te explico, tengo un layout en el que he puesto buttons, imageviews y textviews en el xml, los botones tienen de fondo una imagen como background del button, y las imagene las tengo en la carpeta drawable mdpi, por lo que si, uso drawables. Y en el logcat veo que me da error bitmap exceed vm out of memory, pero yo estoy usando drawables porque nose usar bitmaps todavia. No sé por qué me da ese error.

kriogeN
30/05/12, 22:38:50
Fijate bien en que punto del código te da el Error (porque no es una Exception, es un Error) mirando el trace, porque no debería de ocurrirte.

mocelet
30/05/12, 22:40:06
Ah, vale, en mi caso las imágenes las creaba yo con un Bitmap. Ahí llamar al recycle es lo más eficiente pero es muy muy fácil pifiarla.

Para davidfnt, a ver si el problema es que las imágenes que cargas son muy grandes, ¿tienen el mismo tamaño que el botón o hay que reescalarlas?. Porque siguen siendo mapas de bits a cargar en memoria.

reduv
30/05/12, 23:05:19
Hola, las imágenes que uso son bastante grandes pero las quiero así porque en un Galaxy Note se pixelan si las reduzco, en un principio uso drawables y estos son los errores que me da la aplicación.


05-30 21:02:56.677: E/dalvikvm-heap(586): 1324152-byte external allocation too large for this process.
05-30 21:02:56.920: E/GraphicsJNI(586): VM won't let us allocate 1324152 bytes
05-30 21:02:56.920: D/dalvikvm(586): GC_FOR_MALLOC freed 0K, 57% free 3230K/7367K, external 24322K/26370K, paused 163ms
05-30 21:02:57.017: D/AndroidRuntime(586): Shutting down VM
05-30 21:02:57.017: W/dalvikvm(586): threadid=1: thread exiting with uncaught exception (group=0x40015560)

reduv
30/05/12, 23:40:04
¿Alguna idea de qué significan esos errores y como puedo solucionarlo? Gracias

mocelet
31/05/12, 10:02:40
El problema está muy claro: se están cargando en memoria más imágenes de las que caben.

Ante todo te recomiendo paciencia, te hemos dado algunas pistas de por dónde mirar o cómo resolverlo, pero me temo que no te queda otra que mirar las trazas e incluso entrar en el modo debug a ver con qué tienes llena la memoria.

Tal vez tengas referencias a imágenes guardadas por ahí que aunque no se vean estén en memoria ocupando espacio. O tal vez usas imágenes demasiado grandes para los botones. Puedes mirar si siempre falla en el mismo sitio o es "aleatorio", si es en la primera ejecución de la actividad o cuando ya has cargado más actividades antes.

reduv
31/05/12, 10:36:41
Gracias por vuestra ayuda y por vuestra orientación, el problema que hay es ese, que cargo muchas imágenes y cuando no las muestro siguen estando cargadas. Por eso quería que me indicaseis cómo puedo cargar solo las imágenes que muestro en la pantalla, y cuando no las muestro que no aparezcan, por ejemplo, evitar que el mapa que tengo siga cargado una vez que ya no aparece en pantalla. Esas cosas son las que no entiendo y no sé si tengo que usar bitmaps y cómo meter muchos bitmaps en un solo layout y a la vez mostrarles en un scrollview pero que solo cargue lo que se esté viendo en la pantalla. Espero que me expliquen un poco cómo dejar libre la memoria de cosas que no se muestran. Gracias de nuevo por todo de todas formas

reduv
31/05/12, 10:39:16
Por cierto, en relación a lo que me dices, la actividad que tengo de imágenes y botones y textos no falla siempre, solo cuando cargo el mapa antes. Por eso preguntaba al principio del tema como cerrar este mapa cuando no lo uso para evitar usar memoria. Gracias

reduv
31/05/12, 21:33:10
Hola, alguien que me oriente??