2011-05-20 15 views
27

A continuación se muestra mi fórmula para comprobar la cantidad de memoria restante (no la cantidad de memoria que queda en el montón actual, sino la cantidad de memoria que se puede utilizar antes de que la aplicación falle). No estoy remotamente seguro de que esto sea correcto, ¿verdad?Android: ¿cómo verificar cuánta memoria queda?

double max = Runtime.getRuntime().maxMemory(); //the maximum memory the app can use 
double heapSize = Runtime.getRuntime().totalMemory(); //current heap size 
double heapRemaining = Runtime.getRuntime().freeMemory(); //amount available in heap 
double nativeUsage = Debug.getNativeHeapAllocatedSize(); //is this right? I only want to account for native memory that my app is being "charged" for. Is this the proper way to account for that? 

//heapSize - heapRemaining = heapUsed + nativeUsage = totalUsage 
double remaining = max - (heapSize - heapRemaininng + nativeUsage); 
+0

¿Estoy entendiendo mal algo? ¿Por qué 'getNativeHeapFreeSize()' http://goo.gl/wsBKT no es lo que quería? – Pacerier

+1

La diferencia entre maxMemory() y heapSize() es la cantidad de memoria que puede estar bastante segura de que está disponible para una asignación contigua grande. La cantidad adicional indicada por freeMemory() es la cantidad actualmente no asignada dentro del montón actual, lo que significa que una parte de esa cantidad probablemente esté fragmentada, la cantidad de la cual dependería del incremento utilizado para hacer crecer el montón cuando sea necesario, y cómo gran parte de ese incremento ya se utilizó y luego se devolvió. Entonces, usar su número "restante" arriba puede ser arriesgado si necesita memoria adicional en un bloque contiguo. – Carl

+0

Agregaría que en lugar de probar dinámicamente para ver cuánta memoria hay disponible, probar una cantidad de casos de uso extremo durante el desarrollo para una variedad de valores de maxMemory() y asegurarme de que su aplicación pueda manejarlos podría ser un mejor enfoque. Porque si descubres en cierto punto que te estás acercando a los límites de tu memoria, puede ser difícil deshacerte de lo que estás haciendo de una manera que no sea descortés para el usuario. – Carl

Respuesta

21

Pruebe el siguiente código. eso debería darte los resultados que buscas (especialmente el campo Pss). Puede leer más sobre él here

Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo(); 
Debug.getMemoryInfo(memoryInfo); 

String memMessage = String.format(
    "Memory: Pss=%.2f MB, Private=%.2f MB, Shared=%.2f MB", 
    memoryInfo.getTotalPss()/1024.0, 
    memoryInfo.getTotalPrivateDirty()/1024.0, 
    memoryInfo.getTotalSharedDirty()/1024.0); 
+1

¡Gracias! Entonces, mi interpretación del artículo es que puedo calcular la memoria disponible actualmente como: Runtime.getRuntime(). MaxMemory() - memoryInfo.getTotalPss()? ¿Eso te parece exacto y seguro? – ab11

+0

Me queda bien (aunque no lo he probado ...). por otro lado, podría ser que maxMemory también esté considerando la memoria compartida ya que este es el máximo que puede asignar la VM. así que buscaría más información al respecto ... – Muzikant

+0

Marqué como respondida porque fue útil, pero realmente esta no parecía ser una forma confiable de medir la memoria. Lo que me gustaría es un método que proporcione la cantidad de memoria nativa para la que se carga mi aplicación, que en la mayoría de los casos debería ser la cantidad de memoria asignada para mapas de bits. getTotalPss() no parece devolver esto con precisión, en absoluto. Esta es mi solución final al problema, pensó que no era genial: http://stackoverflow.com/questions/6205496/android-question-about-bitmaps-memory-usage-and-scaling – ab11

2

Se trata de un viejo hilo, pero esto parece funcionar:

Runtime.getRuntime().gc(); 
    long memoryAvailable = (Runtime.getRuntime().maxMemory() - 
     Runtime.getRuntime().totalMemory() + 
     Runtime.getRuntime().freeMemory()); 

totalMemory-freeMemory es la memoria actual utilizado.

Así que esto se reduce a:

(maximum possible memory)-(current used memory)

Editar para agregar:. FreeMemory no cuenta de memoria disponible para la recolección de basura, para que pueda probar Runtime.getRuntime() gc(), aunque se dan cuenta de que puede tener sus propias consecuencias (como hipo visual si se ejecuta en el hilo de UI).

Cuestiones relacionadas