2010-12-03 8 views
5

Tengo una serie de vistas en LinearLayout vertical. Cada vista genera y dibuja un mapa de bits, cuando se desplaza a. Por razones de rendimiento, prefiero no generar el mapa de bits cada vez que se llame a OnDraw(), pero por razones de memoria no puedo mantener referencias duras a los mapas de bits. Podría usar consejos sobre la estrategia que debería tomar.Android: Bitmaps, SoftReferences y OOMs?

Ya probé la ruta obvia de: generar el mapa de bits y luego envolverlo con una referencia suave. Esto falló por dos razones. 1. Las referencias se recogen mucho más ansiosamente de lo que cabría esperar. 2. Todavía tengo OOM! Lo cual es impactante, porque ningún mapa de bits es particularmente grande, por lo que una sola vista no debería causar el OOM, lo que me lleva a suponer que el OOM se produce porque las SoftReference offending no tuvieron la oportunidad de liberarse. Además, el OOM ocurre cuando mi aplicación tiene un tamaño de pila asignado de 6mb (según la vista DDMS), esperaría que crezca a 16mb antes de lanzar OOM.

¿Algún consejo?

+0

reg. "tiene un tamaño de almacenamiento dinámico asignado de 6mb (según la vista DDMS)": lea mi respuesta en: http://stackoverflow.com/questions/3238388/android-out-of-memory-exception-in-gallery ... the 6 mb no es el tamaño asignado tomado por los bitmaps. los mapas de bits toman montón nativo. –

+0

Gracias, probé la estrategia de registro recomendada en su publicación. Esto explica por qué OOM en "6 mb". De acuerdo con su código de registro, OOM cuando mi uso nativo alcanza los 12mb (y el uso de mi aplicación es de aproximadamente 4mb). Lo cual tiene sentido, porque eso es 16mb de uso. Sin embargo, si mis Bitmaps están en SoftReferences, ¿no deberían recopilarse cuando se alcanzan 12mb? – ab11

+0

SoftReferences no tienen nada que ver con el uso de la memoria. – Falmarri

Respuesta

11

El problema es que los Bitmaps usan finalizadores, por lo tanto, podría tomar un par de pases de GC antes de que la memoria original se libere. Esto es algo en lo que estamos trabajando para mejorar.

+0

¿Tiene alguna recomendación mientras tanto? Supongo que debería hacer algo como: mantener algún tipo de seguimiento global de los mapas de bits, y comenzar a liberarlos manualmente si el tamaño agregado de los mapas de bits comienza a volverse peligroso. ¿Algún consejo sobre cómo hacer que tal solución sea menos arbitraria? – ab11

+0

Debería llamar a recycle() manualmente en los mapas de bits usados ​​menos recientemente. –

+0

Supongo que recycle() lo marcará como no utilizado, y luego se limpiará la próxima vez que se ejecute el recolector de basura. Si es así, ¿cómo es esto diferente a usar SoftReference? – ab11