2010-06-25 8 views
54

Gibt es eine API, mit der wir CPU oder Speicherverbrauch von Android bekommen können?Get Memory Usage in Android

Ich habe einen Code versucht, wie unten:

package com.infostretch.mainactivity; 

import java.io.BufferedReader; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 

public class CPULoad 
{ 
    long total = 0; 
    long idle = 0; 

    float usage = 0; 

    public CPULoad() 
    { 
     readUsage(); 
    } 

    public float getUsage() 
    { 
     readUsage(); 
     return usage; 
    } 

    private void readUsage() 
    { 
     try 
     { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/stat")), 1000); 
      String load = reader.readLine(); 
      reader.close(); 

      String[] toks = load.split(" "); 

      long currTotal = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4]); 
      long currIdle = Long.parseLong(toks[5]); 

      this.usage = (currTotal - total) * 100.0f/(currTotal - total + currIdle - idle); 
      this.total = currTotal; 
      this.idle = currIdle; 
     } 
     catch(IOException ex) 
     { 
      ex.printStackTrace(); 
     } 
    } 
} 

Ist dies der richtige Weg, es zu tun?

+1

Vielleicht ein Sie eine Antwort akzeptieren ... – JPM

+0

o/p, was ich bin nicht immer die richtige ist ... die ganze Zeit o/p liegt im Bereich von 0.825699 bis 1.0, nur eine App läuft auf meinem Android-Handy. Ich lade die kostenlose App von Google Play für die CPU-Nutzung prüfen, aber beide o/p ist anders. Kannst du mir sagen, was ich vom Fernsehen bekomme?setText ("" + readCPUUsage()); –

+0

Android Studio verfügt nun über einen Speicherregister, über das Sie alle Informationen zur laufenden App erhalten. – JPM

Antwort

73

Ich benutze diese Funktion, um die CPU-Nutzung zu berechnen. Hoffe es kann dir helfen.

private float readUsage() { 
    try { 
     RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r"); 
     String load = reader.readLine(); 

     String[] toks = load.split(" +"); // Split on one or more spaces 

     long idle1 = Long.parseLong(toks[4]); 
     long cpu1 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[5]) 
       + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]); 

     try { 
      Thread.sleep(360); 
     } catch (Exception e) {} 

     reader.seek(0); 
     load = reader.readLine(); 
     reader.close(); 

     toks = load.split(" +"); 

     long idle2 = Long.parseLong(toks[4]); 
     long cpu2 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[5]) 
      + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]); 

     return (float)(cpu2 - cpu1)/((cpu2 + idle2) - (cpu1 + idle1)); 

    } catch (IOException ex) { 
     ex.printStackTrace(); 
    } 

    return 0; 
} 
+0

Was passiert, wenn Sie nur 1 CPU haben? – ajacian81

+5

Was? Dieser Code funktioniert für eine beliebige Anzahl von Prozessoren und gibt die CPU-Nutzung für alle Prozessoren kombiniert an. – Thalur

+0

Das ist ziemlich lächerlich, aber ich bekomme 1.0, was ich nehme, ist zu 100% die meiste Zeit, obwohl das Gerät keine Anwendungen läuft ... – TacB0sS

2

Überprüfen Sie die Klasse Debug. Debug.getNativeHeapAllocatedSize()

Es hat Methoden, um den verwendeten nativen Heap zu erhalten, der von externen Bitmaps in Ihrer App verwendet wird. Für den Heap, den die App intern verwendet, können Sie dies im DDMS-Tool sehen, das mit dem Android SDK geliefert wird und auch über Eclipse verfügbar ist.

Der native Heap + der Heap, wie in DDMS angegeben, bilden den gesamten Heap, den Ihre App zuweist.

Für die CPU-Nutzung bin ich nicht sicher, ob etwas über API/SDK verfügbar ist.

+0

Siehe auch http://developer.android.com/intl/de/reference/android/os/Debug.html#getMemoryInfo(android.os.Debug.MemoryInfo) –

+0

Hey Mathias..Danke für deine Eingabe, aber ich habe das gefunden Der Code funktioniert sehr gut. Ich war draußen und konnte dir nicht antworten. Bye übrigens, gerade arbeite ich an Speicher-Nutzungspunkt. Ich poste den Code in ein oder zwei Tagen. – Badal

+0

Hallo Mathias .. Ich möchte die aktuelle Speichernutzung in mobilen über meine Anwendung finden, und daher kann DDMS in diesem Szenario nicht helfen. SO, was ich getan habe, habe ich/proc/meminfo Befehl verwendet und die Antwort geparst. aber es zeigt sehr wenig freien Speicher. Ich bin nur verwirrt über die Reaktion. Bitte überprüfen Sie meine Abfrage hier http://stackoverflow.com/questions/3170691/how-to-get-current-memory-usage-in-android – Badal

38

Eine einfache Möglichkeit, die CPU-Auslastung zu überprüfen, ist die Verwendung des ADB-Tools w/top. Dh:

adb shell top -m 10

+0

sehr schön dieser Befehl! – ademar111190

+3

meinst du nicht: "adb shell top -n 1"? –

+4

Obwohl das korrekt ist, war meine Frage über Android API nicht über jedes Tool – Badal

11

Da die OP über die CPU-Auslastung und Speichernutzung gefragt (akzeptierte Antwort zeigt nur Technik CPU-Auslastung zu erhalten), ich möchte die Klasse Activitymanager und speziell die akzeptierte Antwort auf dieser Frage empfehlen : How to get current memory usage in android?

17

Basierend auf den vorherigen Antworten und persönlichen Erfahrungen, hier ist der Code, den ich verwende, um CPU-Auslastung zu überwachen. Der Code dieser Klasse ist in reinem Java geschrieben.

import java.io.IOException; 
import java.io.RandomAccessFile; 

/** 
* Utilities available only on Linux Operating System. 
* 
* <p> 
* A typical use is to assign a thread to CPU monitoring: 
* </p> 
* 
* <pre> 
* &#064;Override 
* public void run() { 
* while (CpuUtil.monitorCpu) { 
* 
*  LinuxUtils linuxUtils = new LinuxUtils(); 
* 
*  int pid = android.os.Process.myPid(); 
*  String cpuStat1 = linuxUtils.readSystemStat(); 
*  String pidStat1 = linuxUtils.readProcessStat(pid); 
* 
*  try { 
*   Thread.sleep(CPU_WINDOW); 
*  } catch (Exception e) { 
*  } 
* 
*  String cpuStat2 = linuxUtils.readSystemStat(); 
*  String pidStat2 = linuxUtils.readProcessStat(pid); 
* 
*  float cpu = linuxUtils.getSystemCpuUsage(cpuStat1, cpuStat2); 
*  if (cpu &gt;= 0.0f) { 
*   _printLine(mOutput, &quot;total&quot;, Float.toString(cpu)); 
*  } 
* 
*  String[] toks = cpuStat1.split(&quot; &quot;); 
*  long cpu1 = linuxUtils.getSystemUptime(toks); 
* 
*  toks = cpuStat2.split(&quot; &quot;); 
*  long cpu2 = linuxUtils.getSystemUptime(toks); 
* 
*  cpu = linuxUtils.getProcessCpuUsage(pidStat1, pidStat2, cpu2 - cpu1); 
*  if (cpu &gt;= 0.0f) { 
*   _printLine(mOutput, &quot;&quot; + pid, Float.toString(cpu)); 
*  } 
* 
*  try { 
*   synchronized (this) { 
*    wait(CPU_REFRESH_RATE); 
*   } 
*  } catch (InterruptedException e) { 
*   e.printStackTrace(); 
*   return; 
*  } 
* } 
* 
* Log.i(&quot;THREAD CPU&quot;, &quot;Finishing&quot;); 
* } 
* </pre> 
*/ 
public final class LinuxUtils { 

    // Warning: there appears to be an issue with the column index with android linux: 
    // it was observed that on most present devices there are actually 
    // two spaces between the 'cpu' of the first column and the value of 
    // the next column with data. The thing is the index of the idle 
    // column should have been 4 and the first column with data should have index 1. 
    // The indexes defined below are coping with the double space situation. 
    // If your file contains only one space then use index 1 and 4 instead of 2 and 5. 
    // A better way to deal with this problem may be to use a split method 
    // not preserving blanks or compute an offset and add it to the indexes 1 and 4. 

    private static final int FIRST_SYS_CPU_COLUMN_INDEX = 2; 

    private static final int IDLE_SYS_CPU_COLUMN_INDEX = 5; 

    /** Return the first line of /proc/stat or null if failed. */ 
    public String readSystemStat() { 

     RandomAccessFile reader = null; 
     String load = null; 

     try { 
      reader = new RandomAccessFile("/proc/stat", "r"); 
      load = reader.readLine(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } finally { 
      Streams.close(reader); 
     } 

     return load; 
    } 

    /** 
    * Compute and return the total CPU usage, in percent. 
    * 
    * @param start 
    *   first content of /proc/stat. Not null. 
    * @param end 
    *   second content of /proc/stat. Not null. 
    * @return 12.7 for a CPU usage of 12.7% or -1 if the value is not 
    *   available. 
    * @see {@link #readSystemStat()} 
    */ 
    public float getSystemCpuUsage(String start, String end) { 
     String[] stat = start.split("\\s"); 
     long idle1 = getSystemIdleTime(stat); 
     long up1 = getSystemUptime(stat); 

     stat = end.split("\\s"); 
     long idle2 = getSystemIdleTime(stat); 
     long up2 = getSystemUptime(stat); 

     // don't know how it is possible but we should care about zero and 
     // negative values. 
     float cpu = -1f; 
     if (idle1 >= 0 && up1 >= 0 && idle2 >= 0 && up2 >= 0) { 
      if ((up2 + idle2) > (up1 + idle1) && up2 >= up1) { 
       cpu = (up2 - up1)/(float) ((up2 + idle2) - (up1 + idle1)); 
       cpu *= 100.0f; 
      } 
     } 

     return cpu; 
    } 

    /** 
    * Return the sum of uptimes read from /proc/stat. 
    * 
    * @param stat 
    *   see {@link #readSystemStat()} 
    */ 
    public long getSystemUptime(String[] stat) { 
     /* 
     * (from man/5/proc) /proc/stat kernel/system statistics. Varies with 
     * architecture. Common entries include: cpu 3357 0 4313 1362393 
     * 
     * The amount of time, measured in units of USER_HZ (1/100ths of a 
     * second on most architectures, use sysconf(_SC_CLK_TCK) to obtain the 
     * right value), that the system spent in user mode, user mode with low 
     * priority (nice), system mode, and the idle task, respectively. The 
     * last value should be USER_HZ times the second entry in the uptime 
     * pseudo-file. 
     * 
     * In Linux 2.6 this line includes three additional columns: iowait - 
     * time waiting for I/O to complete (since 2.5.41); irq - time servicing 
     * interrupts (since 2.6.0-test4); softirq - time servicing softirqs 
     * (since 2.6.0-test4). 
     * 
     * Since Linux 2.6.11, there is an eighth column, steal - stolen time, 
     * which is the time spent in other operating systems when running in a 
     * virtualized environment 
     * 
     * Since Linux 2.6.24, there is a ninth column, guest, which is the time 
     * spent running a virtual CPU for guest operating systems under the 
     * control of the Linux kernel. 
     */ 

     // with the following algorithm, we should cope with all versions and 
     // probably new ones. 
     long l = 0L; 

     for (int i = FIRST_SYS_CPU_COLUMN_INDEX; i < stat.length; i++) { 
      if (i != IDLE_SYS_CPU_COLUMN_INDEX) { // bypass any idle mode. There is currently only one. 
       try { 
        l += Long.parseLong(stat[i]); 
       } catch (NumberFormatException ex) { 
        ex.printStackTrace(); 
        return -1L; 
       } 
      } 
     } 

     return l; 
    } 

    /** 
    * Return the sum of idle times read from /proc/stat. 
    * 
    * @param stat 
    *   see {@link #readSystemStat()} 
    */ 
    public long getSystemIdleTime(String[] stat) { 
     try { 
      return Long.parseLong(stat[IDLE_SYS_CPU_COLUMN_INDEX]); 
     } catch (NumberFormatException ex) { 
      ex.printStackTrace(); 
     } 

     return -1L; 
    } 

    /** Return the first line of /proc/pid/stat or null if failed. */ 
    public String readProcessStat(int pid) { 

     RandomAccessFile reader = null; 
     String line = null; 

     try { 
      reader = new RandomAccessFile("/proc/" + pid + "/stat", "r"); 
      line = reader.readLine(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } finally { 
      Streams.close(reader); 
     } 

     return line; 
    } 

    /** 
    * Compute and return the CPU usage for a process, in percent. 
    * 
    * <p> 
    * The parameters {@code totalCpuTime} is to be the one for the same period 
    * of time delimited by {@code statStart} and {@code statEnd}. 
    * </p> 
    * 
    * @param start 
    *   first content of /proc/pid/stat. Not null. 
    * @param end 
    *   second content of /proc/pid/stat. Not null. 
    * @return the CPU use in percent or -1f if the stats are inverted or on 
    *   error 
    * @param uptime 
    *   sum of user and kernel times for the entire system for the 
    *   same period of time. 
    * @return 12.7 for a cpu usage of 12.7% or -1 if the value is not available 
    *   or an error occurred. 
    * @see {@link #readProcessStat(int)} 
    */ 
    public float getProcessCpuUsage(String start, String end, long uptime) { 

     String[] stat = start.split("\\s"); 
     long up1 = getProcessUptime(stat); 

     stat = end.split("\\s"); 
     long up2 = getProcessUptime(stat); 

     float ret = -1f; 
     if (up1 >= 0 && up2 >= up1 && uptime > 0.) { 
      ret = 100.f * (up2 - up1)/(float) uptime; 
     } 

     return ret; 
    } 

    /** 
    * Decode the fields of the file {@code /proc/pid/stat} and return (utime + 
    * stime) 
    * 
    * @param stat 
    *   obtained with {@link #readProcessStat(int)} 
    */ 
    public long getProcessUptime(String[] stat) { 
     return Long.parseLong(stat[14]) + Long.parseLong(stat[15]); 
    } 

    /** 
    * Decode the fields of the file {@code /proc/pid/stat} and return (cutime + 
    * cstime) 
    * 
    * @param stat 
    *   obtained with {@link #readProcessStat(int)} 
    */ 
    public long getProcessIdleTime(String[] stat) { 
     return Long.parseLong(stat[16]) + Long.parseLong(stat[17]); 
    } 

    /** 
    * Return the total CPU usage, in percent. 
    * <p> 
    * The call is blocking for the time specified by elapse. 
    * </p> 
    * 
    * @param elapse 
    *   the time in milliseconds between reads. 
    * @return 12.7 for a CPU usage of 12.7% or -1 if the value is not 
    *   available. 
    */ 
    public float syncGetSystemCpuUsage(long elapse) { 

     String stat1 = readSystemStat(); 
     if (stat1 == null) { 
      return -1.f; 
     } 

     try { 
      Thread.sleep(elapse); 
     } catch (Exception e) { 
     } 

     String stat2 = readSystemStat(); 
     if (stat2 == null) { 
      return -1.f; 
     } 

     return getSystemCpuUsage(stat1, stat2); 
    } 

    /** 
    * Return the CPU usage of a process, in percent. 
    * <p> 
    * The call is blocking for the time specified by elapse. 
    * </p> 
    * 
    * @param pid 
    * @param elapse 
    *   the time in milliseconds between reads. 
    * @return 6.32 for a CPU usage of 6.32% or -1 if the value is not 
    *   available. 
    */ 
    public float syncGetProcessCpuUsage(int pid, long elapse) { 

     String pidStat1 = readProcessStat(pid); 
     String totalStat1 = readSystemStat(); 
     if (pidStat1 == null || totalStat1 == null) { 
      return -1.f; 
     } 

     try { 
      Thread.sleep(elapse); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return -1.f; 
     } 

     String pidStat2 = readProcessStat(pid); 
     String totalStat2 = readSystemStat(); 
     if (pidStat2 == null || totalStat2 == null) { 
      return -1.f; 
     } 

     String[] toks = totalStat1.split("\\s"); 
     long cpu1 = getSystemUptime(toks); 

     toks = totalStat2.split("\\s"); 
     long cpu2 = getSystemUptime(toks); 

     return getProcessCpuUsage(pidStat1, pidStat2, cpu2 - cpu1); 
    } 

} 

Es gibt mehrere Möglichkeiten, diese Klasse zu nutzen. Sie können entweder syncGetSystemCpuUsage oder syncGetProcessCpuUsage anrufen, aber jeder blockiert den aufrufenden Thread. Da ein häufiges Problem darin besteht, die gesamte CPU-Auslastung und die CPU-Nutzung des aktuellen Prozesses gleichzeitig zu überwachen, habe ich eine Klasse entwickelt, die beide berechnet. Diese Klasse enthält einen dedizierten Thread. Die Ausgabeverwaltung ist implementierungsspezifisch und Sie müssen Ihre eigenen codieren.

Die Klasse kann mit wenigen Mitteln angepasst werden. Die Konstante CPU_WINDOW definiert die Tiefe eines Lesevorgangs, d. H. Die Anzahl von Millisekunden zwischen Lesungen und die Berechnung der entsprechenden CPU-Last. CPU_REFRESH_RATE ist die Zeit zwischen jeder CPU-Lastmessung. Setzen Sie CPU_REFRESH_RATE nicht auf 0, da der Thread nach dem ersten Lesevorgang angehalten wird.

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.OutputStream; 

import android.app.Application; 
import android.os.Handler; 
import android.os.HandlerThread; 
import android.util.Log; 

import my.app.LinuxUtils; 
import my.app.Streams; 
import my.app.TestReport; 
import my.app.Utils; 

public final class CpuUtil { 

    private static final int CPU_WINDOW = 1000; 

    private static final int CPU_REFRESH_RATE = 100; // Warning: anything but > 0 

    private static HandlerThread handlerThread; 

    private static TestReport output; 

    static { 
     output = new TestReport(); 
     output.setDateFormat(Utils.getDateFormat(Utils.DATE_FORMAT_ENGLISH)); 
    } 

    private static boolean monitorCpu; 

    /** 
    * Construct the class singleton. This method should be called in 
    * {@link Application#onCreate()} 
    * 
    * @param dir 
    *   the parent directory 
    * @param append 
    *   mode 
    */ 
    public static void setOutput(File dir, boolean append) { 
     try { 
      File file = new File(dir, "cpu.txt"); 
      output.setOutputStream(new FileOutputStream(file, append)); 
      if (!append) { 
       output.println(file.getAbsolutePath()); 
       output.newLine(1); 

       // print header 
       _printLine(output, "Process", "CPU%"); 

       output.flush(); 
      } 

     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 

    /** Start CPU monitoring */ 
    public static boolean startCpuMonitoring() { 
     CpuUtil.monitorCpu = true; 

     handlerThread = new HandlerThread("CPU monitoring"); //$NON-NLS-1$ 
     handlerThread.start(); 

     Handler handler = new Handler(handlerThread.getLooper()); 
     handler.post(new Runnable() { 

      @Override 
      public void run() { 
       while (CpuUtil.monitorCpu) { 

        LinuxUtils linuxUtils = new LinuxUtils(); 

        int pid = android.os.Process.myPid(); 
        String cpuStat1 = linuxUtils.readSystemStat(); 
        String pidStat1 = linuxUtils.readProcessStat(pid); 

        try { 
         Thread.sleep(CPU_WINDOW); 
        } catch (Exception e) { 
        } 

        String cpuStat2 = linuxUtils.readSystemStat(); 
        String pidStat2 = linuxUtils.readProcessStat(pid); 

        float cpu = linuxUtils 
          .getSystemCpuUsage(cpuStat1, cpuStat2); 
        if (cpu >= 0.0f) { 
         _printLine(output, "total", Float.toString(cpu)); 
        } 

        String[] toks = cpuStat1.split(" "); 
        long cpu1 = linuxUtils.getSystemUptime(toks); 

        toks = cpuStat2.split(" "); 
        long cpu2 = linuxUtils.getSystemUptime(toks); 

        cpu = linuxUtils.getProcessCpuUsage(pidStat1, pidStat2, 
          cpu2 - cpu1); 
        if (cpu >= 0.0f) { 
         _printLine(output, "" + pid, Float.toString(cpu)); 
        } 

        try { 
         synchronized (this) { 
          wait(CPU_REFRESH_RATE); 
         } 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
         return; 
        } 
       } 

       Log.i("THREAD CPU", "Finishing"); 
      } 

     }); 

     return CpuUtil.monitorCpu; 
    } 

    /** Stop CPU monitoring */ 
    public static void stopCpuMonitoring() { 
     if (handlerThread != null) { 
      monitorCpu = false; 
      handlerThread.quit(); 
      handlerThread = null; 
     } 
    } 

    /** Dispose of the object and release the resources allocated for it */ 
    public void dispose() { 

     monitorCpu = false; 

     if (output != null) { 
      OutputStream os = output.getOutputStream(); 
      if (os != null) { 
       Streams.close(os); 
       output.setOutputStream(null); 
      } 

      output = null; 
     } 
    } 

    private static void _printLine(TestReport output, String process, String cpu) { 
     output.stampln(process + ";" + cpu); 
    } 

} 
-2

geben Sie das Android-Terminal und dann können Sie die folgenden Befehle eingeben: dumpsys cpuinfo

[email protected]:/ $ dumpsys cpuinfo            
Load: 0.8/0.75/1.15 
CPU usage from 69286ms to 9283ms ago with 99% awake: 
    47% 1118/com.wxg.sodproject: 12% user + 35% kernel 
    1.6% 1225/android.process.media: 1% user + 0.6% kernel 
    1.3% 263/mpdecision: 0.1% user + 1.2% kernel 
    0.1% 32747/kworker/u:1: 0% user + 0.1% kernel 
    0.1% 883/com.android.systemui: 0.1% user + 0% kernel 
    0.1% 521/system_server: 0.1% user + 0% kernel/faults: 14 minor 
    0.1% 1826/com.quicinc.trepn: 0.1% user + 0% kernel 
    0.1% 2462/kworker/0:2: 0.1% user + 0% kernel 
    0.1% 32649/kworker/0:0: 0% user + 0.1% kernel 
    0% 118/mmcqd/0: 0% user + 0% kernel 
    0% 179/surfaceflinger: 0% user + 0% kernel 
    0% 46/kinteractiveup: 0% user + 0% kernel 
    0% 141/jbd2/mmcblk0p26: 0% user + 0% kernel 
    0% 239/sdcard: 0% user + 0% kernel 
    0% 1171/com.xiaomi.channel:pushservice: 0% user + 0% kernel/faults: 1 minor 
    0% 1207/com.xiaomi.channel: 0% user + 0% kernel/faults: 1 minor 
    0% 32705/kworker/0:1: 0% user + 0% kernel 
12% TOTAL: 3.2% user + 9.4% kernel + 0% iowait 
+0

Der Fragesteller suchte nach einer API (Application Programming Interface), um diese Informationen zu erhalten. –

+0

Kann nur von System-Apps aufgerufen werden, also nicht per Anruf innerhalb von Android-App als Frage geeignet. – tommed