Pregunta

Estoy haciendo un juego que tiene que cargar todos los mapas de bits al inicio porque en el editor de juegos incorporado el usuario puede poner cualquiera de los sprites en el nivel. También los niveles usan varios sprites sin ningún sistema que permita cargar grupos de sprites dinámicamente para cada nivel.

Después de un tiempo, ya ya están ya más de 250 imágenes PNG en el juego con un tamaño total de 3.5 MB.

El juego carga la mayoría de los sprites (alrededor de 200) usando bitmapFactory.CodeStream sin ningún conjunto de opciones, y también hay otros 50 a los que se hace referencia en diseños XML de actividades.

Cuando pruebo en varios dispositivos, el juego a veces se queda sin memoria, pero no puedo encontrar un patrón e incluso decidir cuánto tengo que, por ejemplo, reducir el tamaño de las imágenes o su número.

El teléfono en el que desarrollé, HTC Desire con Android 2.2 24MB VM Tamaño del montón nunca funciona con OOM.

La racha de Dell con Android 2.2 y 40 MB VM Tamaño del montón nunca ejecuta OOM también.

Motorola Milestone con Android 2.1 y 24 MB VM El tamaño del montón Carga con éxito todos los sprites, pero se ahoga en las pocas últimas imágenes utilizadas en ImageView cuando se inicia una de las actividades (menú de inicio). Si comento algunas de esas imágenes, se carga bien, pero puede ahogarse en una de las otras actividades más adelante. Tampoco es estable, probablemente porque la fragmentación ocurre de manera diferente en diferentes lanzamientos.

HTC Hero con 2.2 de mi amigo (no sé el tamaño del montón, ¿es 16 MB?) También se bloquea.

Lo más confuso es que Motorola tiene 24 MB, lo mismo que HTC Desire. ¿2.1 implementar la gestión de la memoria de manera menos eficiente? (¿Por ejemplo, conduce a más fragmentación?) ¿O todos los teléfonos Motorola peor a la gestión de la memoria? Entonces, ¿por qué HTC Hero con 2.2 se estrella? ¿Qué es más grande en HTC Desire que HTC Hero?

Parece que OOM sucede en los teléfonos más antiguos, pero eso es lo único que he descubierto hasta ahora.

Si OOM solo ocurre en teléfonos más antiguos que, por ejemplo, el 5% del mercado, puedo excluir 2.1 o una lista más específica de los dispositivos compatibles simplemente reuniendo informes de accidentes y excluyendo todo lo que se bloqueó de la lista de compatibles. De lo contrario, ahora necesitaría escalar todas mis imágenes por algún factor constante (por ejemplo, 1.6), lo que significaría cambiar el tamaño de los 45 niveles que tomaron días y días de diseño y pruebas, reposicionando elementos de la GUI, etc., incluso después de eso, yo 'yo' ' D todavía no esté seguro, en qué dispositivos la reducción del tamaño total de mapas de bits por un factor de EG 2 es suficiente para evitar los OOMS.

¿Algún consejo sobre esto? ¿Debo establecer alguna opción específica para BitMapFactory? Por cierto, la mayoría de las imágenes tienen píxeles BG transparentes que, por lo que yo entiendo, no permiten obtenerlas en formato 565.

Pasé 2 días navegando aquí y en otros lugares, pero todavía estoy perdido.

Gracias.

¿Fue útil?

Solución

He tenido que lidiar con una versión más simple de su problema: teníamos 3 capas 2MPIX una encima de la otra, lo que, como era de esperar, a veces causaba OOM.

En mi caso, en lugar de usar 3 vistas de imagen una encima de la otra, manteniendo las 6 MPIX en la memoria en todo momento, combiné manualmente las capas, manteniendo así como máximo 4 MPIX en la memoria en cualquier momento (y solo 2 MPIX AT " REST " - Las capas cambiaron en nuestra aplicación).

Esta es una compensación clásica del espacio de tiempo: la eficiencia de sacrificio (tiempo) para ganar memoria (espacio). Fue algo lento porque tenías que recycle() Cada mapa de bits después de haber terminado para asegurarse de que se liberara la memoria.

En cuanto a los Ooms inconsistentes, probablemente tenga que ver con la recolección de basura. Puede suponer que el recolector de basura no es determinista y, por lo tanto, cualquier presión de memoria también se vuelve no determinista (dependiendo de cuándo se activó el GC).

El breve resumen es que debes ser muy, muy cuidadoso con el uso de tu memoria y no hay forma de evitarlo. *

* En teoría, puede asignar memoria fuera del montón de Dalvik usando el NDK y asignando directamente desde el sistema operativo. Es un gran truco y el puente entre Dalvik y su asignador será bastante feo.

Otros consejos

Primero debe encontrar qué es exactamente el uso de toda su memoria. Mira esto. Tal vez podrías reciclar mapas de bits, por ejemplo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top