2012-02-28 12 views
6

Tengo una aplicación para Android OpenGL que usa una cantidad considerable de memoria para configurar una escena compleja y esto claramente causa una fragmentación de montón significativa. Aunque no hay pérdidas de memoria, es imposible destruir y crear la aplicación sin que se quede sin memoria debido a la fragmentación. (La fragmentación es definitivamente el problema, no fugas)Android Heap Fragmentation Strategy?

Esto causa un problema importante ya que Android tiene la costumbre de destruir y crear actividades en la misma máquina virtual/montón que obviamente hace que la actividad se bloquee. Como una estrategia para contrarrestar esto he utilizado la siguiente técnica:

@Override 
protected void onStop() { 
    super.onStop(); 
    if(isFinishing()) { 
     System.runFinalizersOnExit(true); 
     System.exit(0); 
    } 
} 

Esto asegura que cuando la actividad está terminando causa una completa parada de máquina virtual y, por tanto, la próxima vez que se inicie la actividad se pone un montón sin fragmentar fresco.

Nota: Me doy cuenta de que esta no es la "forma de Android", pero dado que el recolector de basura no es compactante, es imposible reutilizar continuamente el montón.

Este techinque realmente funciona en general, sin embargo, no funciona cuando la actividad se destruye en un modo sin acabado y luego se vuelve a crear.

¿Alguien ha recibido alguna sugerencia sobre cómo manejar la degradación del montón?

Nota adicional: Reducir el consumo de memoria tampoco es una opción. La actividad en realidad no usa tanta memoria, pero el montón (y el montón nativo) parecen fragmentarse fácilmente, probablemente debido a algunos trozos grandes de memoria

+0

tuve el mismo problema y empleé una solución similar. realmente terrible –

Respuesta

4

La fragmentación es casi siempre una consecuencia de una mala asignación condicionada patrón. Los objetos grandes se crean y destruyen con frecuencia. En conjunción con objetos más pequeños puede persistir (o al menos tener una vida útil diferente) - se crean agujeros en el montón.

La única prevención de fragmentación que funciona en tales escenarios es: prevenir el patrón de asignación específico. Esto a menudo se puede hacer agrupando los objetos grandes. Si tiene éxito, la aplicación agradece reconocer esto con una velocidad de ejecución mucho mejor también.

@edit: aún más específico para su pregunta: si el montón después de un reinicio de la aplicación todavía no está vacío, entonces ¿qué hay para permanecer en el montón? Usted confirmó que no es un problema de pérdida de memoria, pero esto es lo que parece. Ya que está usando OpenGL - ¿podría ser posible ?, algunas envolturas nativas han sobrevivido, porque los recursos de OpenGL no se han eliminado correctamente.