2010-07-03 12 views
82

Ho usato/proc/meminfo e comando response.however è risultato analizzato mostra che:Come ottenere l'utilizzo della memoria corrente in Android?

MemTotal: 94348 kB MemFree: 5784 kB

mezzi. mostra che c'è solo 5 MB di memoria libera. È possibile con Android Mobile? Sul mio cellulare è installata solo un'applicazione 5-6 e nessun'altra attività è in esecuzione. ma ancora questo comando mostra che c'è pochissima memoria libera.

Qualcuno può chiarirlo? o c'è qualche altro modo per ottenere l'utilizzo della memoria in Android?

+1

Stai cercando di visualizzare la memoria libera per dispositivo o per app? Se per app, deve essere calcolato sull'heap a-la 'Debug.getNativeHeapFreeSize()'. –

+0

Per calcolare la memoria libera (in RAM) usando/proc/meminfo è necessario ottenere l'aggregato di * MemFree *, * Buffers *, * Cached * e * SwapCached *. C'è un'API per questo scopo fornita da Android che funziona su API 16 e su reparti. Meminfo è utile se stai prendendo di mira API precedenti. –

risposta

138

ATTENZIONE: Questo utilizzo della memoria misure di risposta/a disposizione del dispositivo. Questo NON è ciò che è disponibile per la tua app. Per misurare ciò che la tua APP sta facendo, ed è PERMESSO, Use android developer's answer.


Android docs - ActivityManager.MemoryInfo

  1. parse/proc/meminfo comando.È possibile trovare il codice di riferimento qui: Get Memory Usage in Android

  2. uso sotto il codice e ottenere RAM corrente:

    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; 
    

Spiegazione del numero 0x100000L

1024 bytes  == 1 Kibibyte 
1024 Kibibyte == 1 Mebibyte 

1024 * 1024  == 1048576 
1048576   == 0x100000 

E 'abbastanza ovvio che il il numero viene utilizzato per convertire da byte a mebibyte

P.S: dobbiamo calcolare la memoria totale solo una volta. quindi chiama il punto 1 una sola volta nel tuo codice e poi dopo, puoi chiamare ripetutamente il codice del punto 2.

+0

Voglio controllare la dimensione della memoria. Che cos'è MemoryInfo? – Piraba

+0

PIraba, la sua classe API Android. Controllalo qui http://developer.android.com/reference/android/app/ActivityManager.MemoryInfo.html. – Badal

+0

@SanjayJoshi Questo perché la variabile availMem contiene la memoria in byte. 1024 byte equivalgono a 1 KiloByte e 1024 kilobyte a 1 MegaByte. Quindi 1024 * 1024 è uguale a 1048576 –

12

La filosofia di gestione della memoria di Linux è "La memoria libera è memoria sprecata".

Suppongo che le prossime due righe mostreranno quanto memoria è in "Buffer" e quanto è "In cache". Mentre c'è una differenza tra i due (per favore non chiedere quale sia questa differenza :) entrambi sommano approssimativamente la quantità di memoria usata per memorizzare i dati dei file e i metadati.

Una guida molto più utile per liberare memoria su un sistema Linux è il comando free(1); sul mio desktop, riporta le informazioni in questo modo:

 
$ free -m 
      total  used  free  shared buffers  cached 
Mem:   5980  1055  4924   0   91  374 
-/+ buffers/cache:  589  5391 
Swap:   6347   0  6347 

La +/- buffer/cache: la linea è la linea magica, si riferisce che ho davvero avuto intorno a 589 mega di memoria processo necessario attivamente, e intorno 5391 mega di memoria "libera", nel senso che i 91 + 374 megabyte di memoria buffer/cache possono essere gettati via se la memoria potrebbe essere utilizzata in modo più proficuo altrove.

(La mia macchina è stato per circa tre ore, facendo quasi nulla, ma StackOverflow, che è il motivo per cui ho tanto libera di memoria.)

Se Android non viene fornito con free(1), si può fare la matematica te stesso con il file /proc/meminfo; Mi piace solo il formato di output free(1). :)

+0

libero non è un comando di shell adb ... –

+1

@Igor, quindi ti consigliamo di 'cat/proc/meminfo' invece. È molto più dettagliato, ma 'MemFree'. 'Buffer', e' Cached' sono probabilmente le linee più importanti. – sarnold

+0

Ha funzionato, grazie! –

16

Un altro modo (attualmente in mostra 25 MB liberi sul mio G1):

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

Hey Alex, Grazie mille per il tuo aiuto! 1 altra domanda. Questo codice mi dà RAM disponibile. Voglio anche visualizzare la RAM totale. Come ottenerlo? – Badal

+0

@Badal Non conosco un'API Java per questo. Attenersi ad analizzare/proc/meminfo. – yanchenko

+4

sempre visualizzato 0.0 –

28

Ecco un modo per calcolare l'utilizzo della memoria di applicazione attualmente in esecuzione:

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; 

} 
+4

È un approccio semplice, ma come è stato indicato nella documentazione, il metodo freeMemory() della classe Runtime restituisce la memoria disponibile per il programma o l'applicazione corrente. Quindi, tieni presente questo durante l'utilizzo. – Fatih

+1

è sbagliato modo ... – Peter

+0

@Peter - Sì, è "sbagliato" in quanto risponde a una domanda diversa da quella richiesta.D'altra parte, questo è "giusto" per ciò che uno sviluppatore di app di solito ha bisogno di sapere: raramente importa quale sia lo stato generale della memoria sul DISPOSITIVO - se l'utente ha eseguito molte app, il SO * dovrebbe * fare uso di la maggior parte della sua memoria, altrimenti è inefficiente. Il sistema operativo deve sapere che cosa offre la risposta accettata, sapere quando iniziare ad uccidere le app che non sono state utilizzate di recente. Ma un programmatore di app deve sapere cosa questa risposta (e la risposta simile dello sviluppatore di Android) ti dice, rispetto a runtime.maxMemory. – ToolmakerSteve

1

è anche possibile utilizzare lo strumento DDMS che fa parte di Android SDK è di per sé. aiuta ad ottenere allocazioni di memoria di codice java e codice c/C++ nativo.

+1

Dovresti anche dirci come usarlo, non solo dire "usa questo" ... – not2qubit

4

Ho guardato l'albero delle origini di Android.

All'interno di com.android.server.am. ActivityManagerService.java (servizio interno esposto da 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); 
} 

All'interno di android.os. Process.java

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

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

Si chiama metodo JNI da android_util_Process.cpp

Conclusione

MemoryInfo.availMem = MemFree + cache in/proc/meminfo.

Note

memoria totale viene aggiunto nel livello di API 16.

+0

Mi piace il tuo risponditore – wukong

42

Essa dipende dalla vostra definizione di ciò interrogazione memoria che si desidera ottenere.


Di solito, si desidera conoscere lo stato della memoria heap, in quanto se si utilizza troppa memoria, si ottiene OOM e crash l'applicazione.

Per questo, è possibile controllare i valori prossimi:

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

Quanto più il "usedMemInMB" variabile si avvicina a "maxHeapSizeInMB", il più vicino availHeapSizeInMB arriva a zero, più ci si avvicina OOM. (A causa della frammentazione della memoria, è possibile ottenere OOM PRIMA che ciò raggiunga lo zero.)

Questo è anche ciò che mostra lo strumento DDMS dell'utilizzo della memoria.


In alternativa, c'è il vero utilizzo di RAM, che è quanto l'intero sistema utilizza - vedi accepted answer calcolare che.

+0

Questo è molto utile –

+0

Wow. Così semplice, eppure così vero! – Ran

5

Mi riferisco a pochi scritti.

riferimento:

Questo metodo getMemorySize() viene restituito MemorySize che ha dimensione totale e libera memoria.
Non credo questo codice perfettamente.
Questo codice sta testando su 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; 
    } 

So che Pattern.compile() è il costo costoso così si può spostare il suo codice a membro della classe.

0
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; 
} 
Problemi correlati