¿Cómo obtener el uso actual de la memoria en Android?

He usado / proc / meminfo y la respuesta de comando analizada. Sin embargo, el resultado muestra que:

MemTotal: 94348 kB MemFree: 5784 kB

medio. muestra que solo hay 5 MB de memoria libre. ¿Es posible con el móvil Android? Solo hay 5-6 aplicaciones instaladas en mi dispositivo móvil y no se está ejecutando ninguna otra tarea. pero aún así este comando muestra que hay muy poca memoria libre.

¿Alguien puede aclarar esto? o hay alguna otra forma de obtener el uso de la memoria en Android?

PRECAUCIÓN: esta respuesta mide el uso de memoria / disponible del DISPOSITIVO. Esto NO es lo que está disponible para su aplicación. Para medir lo que está haciendo su aplicación, y está PERMITIDO hacerlo, use la respuesta del desarrollador de Android .


Documentos de Android – ActivityManager.MemoryInfo

  1. comando parse / proc / meminfo. Aquí puede encontrar el código de referencia: Obtenga uso de la memoria en Android

  2. use el código debajo y obtenga la RAM actual:

     MemoryInfo mi = new MemoryInfo(); ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); activityManager.getMemoryInfo(mi); double availableMegs = mi.availMem / 0x100000L; //Percentage can be calculated for API 16+ double percentAvail = mi.availMem / (double)mi.totalMem * 100.0; 

Explicación del número 0x100000L

 1024 bytes == 1 Kibibyte 1024 Kibibyte == 1 Mebibyte 1024 * 1024 == 1048576 1048576 == 0x100000 

Es bastante obvio que el número se usa para convertir de bytes a mebibyte

PD: necesitamos calcular la memoria total solo una vez. así que llame al punto 1 solo una vez en su código y luego, puede llamar al código del punto 2 repetitivamente.

Depende de su definición de qué consulta de memoria desea obtener.


Por lo general, le gustaría saber el estado de la memoria Heap, ya que si usa demasiada memoria, obtiene OOM y bloquea la aplicación.

Para esto, puedes verificar los siguientes valores:

 final Runtime runtime = Runtime.getRuntime(); final long usedMemInMB=(runtime.totalMemory() - runtime.freeMemory()) / 1048576L; final long maxHeapSizeInMB=runtime.maxMemory() / 1048576L; final long availHeapSizeInMB = maxHeapSizeInMB - usedMemInMB; 

Cuanto más se acerque la variable “usedMemInMB” a “maxHeapSizeInMB”, cuanto más cerca availHeapSizeInMB el availHeapSizeInMB de cero, más se acercará a OOM. (Debido a la fragmentación de la memoria, puede obtener OOM ANTES de que llegue a cero).

Eso es también lo que muestra la herramienta DDMS de uso de memoria.


Alternativamente, existe el uso real de la RAM, que es la cantidad que utiliza todo el sistema – ver la respuesta aceptada para calcular eso.


Actualización: desde Android O hace que su aplicación también use la RAM nativa (al menos para el almacenamiento de Bitmaps, que suele ser la razón principal para un gran uso de memoria), y no solo el montón, las cosas han cambiado y obtiene menos OOM (porque el heap ya no contiene bitmaps, verifique aquí ), pero aún debe vigilar el uso de la memoria si sospecha que tiene pérdidas de memoria. En Android O, si tiene pérdidas de memoria que deberían haber causado OOM en versiones anteriores, parece que se bloqueará sin que pueda atraparlo. A continuación se explica cómo verificar el uso de la memoria:

  val nativeHeapSize = Debug.getNativeHeapSize() val nativeHeapFreeSize = Debug.getNativeHeapFreeSize() val usedMemInBytes = nativeHeapSize - nativeHeapFreeSize val usedMemInPercentage = usedMemInBytes * 100 / nativeHeapSize 

Pero creo que sería mejor usar el generador de perfiles del IDE, que muestra los datos en tiempo real, usando un gráfico.

Entonces, la buena noticia sobre Android O es que es mucho más difícil obtener lockings debido a OOM de almacenar demasiados mapas de bits de gran tamaño, pero la mala noticia es que no creo que sea posible detectar ese caso durante el tiempo de ejecución.

Aquí hay una forma de calcular el uso de la memoria de la aplicación que se está ejecutando actualmente :

 public static long getUsedMemorySize() { long freeSize = 0L; long totalSize = 0L; long usedSize = -1L; try { Runtime info = Runtime.getRuntime(); freeSize = info.freeMemory(); totalSize = info.totalMemory(); usedSize = totalSize - freeSize; } catch (Exception e) { e.printStackTrace(); } return usedSize; } 

Otra forma (actualmente muestra 25 MB gratis en mi G1):

 MemoryInfo mi = new MemoryInfo(); ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); activityManager.getMemoryInfo(mi); long availableMegs = mi.availMem / 1048576L; 

La filosofía de administración de memoria de Linux es “La memoria gratuita es una memoria desperdiciada”.

Supongo que las siguientes dos líneas mostrarán cuánta memoria hay en “Buffers” y cuánto está “Cached”. Si bien existe una diferencia entre los dos (no pregunte cuál es la diferencia), ambos sumn aproximadamente la cantidad de memoria utilizada para almacenar en caché los datos de los archivos y los metadatos.

Una guía mucho más útil para liberar memoria en un sistema Linux es el comando free(1) ; en mi escritorio, informa información como esta:

 $ free -m
              Total de búferes compartidos libres utilizados en caché
 Mem: 5980 1055 4924 0 91 374
 - / + buffers / caché: 589 5391
 Intercambio: 6347 0 6347

La línea +/- buffers / cache: es la línea mágica, informa que realmente tengo alrededor de 589 megas de memoria de proceso requerida activamente, y alrededor de 5391 megs de memoria ‘libre’, en el sentido de que los 91 + 374 megabytes de memorias intermedias / memoria almacenada en caché puede desecharse si la memoria se puede utilizar de forma más rentable en otro lugar.

(Mi máquina ha estado funcionando durante aproximadamente tres horas, haciendo casi nada más que stackoverflow, por lo que tengo tanta memoria libre).

Si Android no se envía free(1) , puede hacer los cálculos usted mismo con el archivo /proc/meminfo ; Simplemente me gusta el formato de salida free(1) . 🙂

Me refiero a algunas escrituras.

referencia:

Este método getMemorySize () se devuelve MemorySize que tiene un tamaño de memoria total y libre.
No creo este código a la perfección.
Este código está probando en LG G3 cat.6 (v5.0.1)

  private MemorySize getMemorySize() { final Pattern PATTERN = Pattern.compile("([a-zA-Z]+):\\s*(\\d+)"); MemorySize result = new MemorySize(); String line; try { RandomAccessFile reader = new RandomAccessFile("/proc/meminfo", "r"); while ((line = reader.readLine()) != null) { Matcher m = PATTERN.matcher(line); if (m.find()) { String name = m.group(1); String size = m.group(2); if (name.equalsIgnoreCase("MemTotal")) { result.total = Long.parseLong(size); } else if (name.equalsIgnoreCase("MemFree") || name.equalsIgnoreCase("Buffers") || name.equalsIgnoreCase("Cached") || name.equalsIgnoreCase("SwapFree")) { result.free += Long.parseLong(size); } } } reader.close(); result.total *= 1024; result.free *= 1024; } catch (IOException e) { e.printStackTrace(); } return result; } private static class MemorySize { public long total = 0; public long free = 0; } 

Sé que Pattern.compile () es costoso, así que puedes mover su código al miembro de la clase.

Miré a Android Source Tree.

Dentro de com.android.server.am. ActivityManagerService.java (servicio interno expuesto por android.app. ActivityManager ).

 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); outInfo.availMem = Process.getFreeMemory(); outInfo.totalMem = Process.getTotalMemory(); outInfo.threshold = homeAppMem; outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); outInfo.hiddenAppThreshold = hiddenAppMem; outInfo.secondaryServerThreshold = mProcessList.getMemLevel( ProcessList.SERVICE_ADJ); outInfo.visibleAppThreshold = mProcessList.getMemLevel( ProcessList.VISIBLE_APP_ADJ); outInfo.foregroundAppThreshold = mProcessList.getMemLevel( ProcessList.FOREGROUND_APP_ADJ); } 

Dentro de android.os. Process.java

 /** @hide */ public static final native long getFreeMemory(); /** @hide */ public static final native long getTotalMemory(); 

Llama al método JNI de android_util_Process.cpp

Conclusión

MemoryInfo.availMem = MemFree + En caché en / proc / meminfo.

Notas

La memoria total se agrega en el nivel de API 16.

también puedes usar la herramienta DDMS que es parte del SDK de Android. también ayuda a obtener asignaciones de memoria de código Java y código c / c ++ nativo.

 public static boolean isAppInLowMemory(Context context) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); return memoryInfo.lowMemory; }