Получить использование памяти в Android - PullRequest
57 голосов
/ 25 июня 2010

Есть ли какой-нибудь API, с помощью которого мы можем получить использование процессора или памяти Android?

Я попробовал один код, как показано ниже:

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();
        }
    }
}

Это правильный способ сделать это?

Ответы [ 6 ]

75 голосов
/ 06 апреля 2011

Я использую эту функцию для расчета загрузки процессора. Надеюсь, это поможет вам.

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;
} 
38 голосов
/ 22 июня 2011

Простой способ проверить загрузку процессора - использовать инструмент adb w / top. I.e.:

adb shell top -m 10

17 голосов
/ 12 ноября 2012

Исходя из предыдущих ответов и личного опыта, вот код, который я использую для мониторинга использования процессора.Код этого класса написан на чистом Java.

<code>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;);
 * }
 * 
* / public final class LinuxUtils {// Предупреждение: существует проблема с индексом столбца в android linux: // было замечено, что на большинствеВ настоящее время у устройств фактически есть // два пробела между «процессором» первого столбца и значением // следующего столбца с данными.Дело в том, что индекс столбца idle // должен быть равен 4, а первый столбец с данными должен иметь индекс 1. // Определенные ниже индексы справляются с ситуацией двойного пробела.// Если ваш файл содержит только один пробел, тогда используйте индексы 1 и 4 вместо 2 и 5. // Лучшим способом решения этой проблемы может быть использование метода split // без сохранения пробелов или вычисления смещения и его добавленияк индексам 1 и 4. приватная статическая final int FIRST_SYS_CPU_COLUMN_INDEX = 2;private static final int IDLE_SYS_CPU_COLUMN_INDEX = 5;/ ** Вернуть первую строку / proc / stat или null, если не удалось.* / public String readSystemStat () {RandomAccessFile reader = null;Нагрузка на строку = ноль;try {reader = new RandomAccessFile ("/ proc / stat", "r");load = reader.readLine ();} catch (IOException ex) {ex.printStackTrace ();} finally {Streams.close (читатель);} возврат нагрузки;} / ** * Вычисляет и возвращает общее использование процессора в процентах.* * @param start * первое содержимое / proc / stat.Ненулевой.* @param end * второй контент / proc / stat.Ненулевой.* @return 12,7 для использования ЦП 12,7% или -1, если значение * недоступно.* @see {@link #readSystemStat ()} * / public float getSystemCpuUsage (начало строки, конец строки) {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);// не знаю, как это возможно, но мы должны заботиться о нулевых и // отрицательных значениях.число с плавающей запятой = -1f;if (idle1> = 0 && up1> = 0 && idle2> = 0 && up2> = 0) {if ((up2 + idle2)> (up1 + idle1) && up2> = up1) {cpu = (up2 - up1)/ (плавать) ((up2 + idle2) - (up1 + idle1));процессор * = 100,0f;}} return cpu;} / ** * Возвращает сумму времени простоя, прочитанного из / proc / stat.* * @param stat * see {@link #readSystemStat ()} * / public long getSystemUptime (String [] stat) {/ * * (из man / 5 / proc) / proc / stat ядро ​​/ системная статистика.Зависит от * архитектуры.Общие записи включают в себя: процессор 3357 0 4313 1362393 * * Количество времени, измеренное в единицах USER_HZ (1/100-ые * секунды на большинстве архитектур, используйте sysconf (_SC_CLK_TCK) для получения * правильного значения), которое система потратилав пользовательском режиме, пользовательском режиме с низким * приоритетом (приятно), системном режиме и задаче ожидания, соответственно.* Последнее значение должно быть USER_HZ, умноженное на вторую запись в псевдофайле uptime *.* * В Linux 2.6 эта строка включает три дополнительных столбца: iowait - * время ожидания завершения ввода / вывода (с 2.5.41);irq - время обслуживания * прерываний (начиная с 2.6.0-test4);softirq - время обслуживания softirqs * (начиная с 2.6.0-test4).* * Начиная с Linux 2.6.11, существует восьмой столбец, «украденное - украденное время», * который представляет собой время, проведенное в других операционных системах при работе в * виртуализированной среде * * Начиная с Linux 2.6.24, существует девятый столбец,гость, который время* потратил на запуск виртуального процессора для гостевых операционных систем под * контролем ядра Linux.* / // со следующим алгоритмом, мы должны справиться со всеми версиями и // возможно новыми.длинный l = 0L;for (int i = FIRST_SYS_CPU_COLUMN_INDEX; i * Параметры {@code totalCpuTime} должны быть такими же для того же периода времени *, разделенного {@code statStart} и {@code statEnd}.* * * @param start * первое содержимое / proc / pid / stat.Ненулевой.* @param end * второй контент / proc / pid / stat.Ненулевой.* @return использование ЦП в процентах или -1f, если статистика инвертирована или включена * error * @param uptime * сумма времени пользователя и ядра для всей системы за * тот же период времени.* @return 12,7 для использования ЦП 12,7% или -1, если значение недоступно * или произошла ошибка.* @see {@link #readProcessStat (int)} * / public float getProcessCpuUsage (начало строки, конец строки, длительное время работы) {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;} / ** * Расшифровать поля файла {@code / proc / pid / stat} и вернуть (utime + * stime) * * @param stat *, полученное с помощью {@link #readProcessStat (int)} * / public longgetProcessUptime (String [] stat) {return Long.parseLong (stat [14]) + Long.parseLong (stat [15]);} / ** * Декодировать поля файла {@code / proc / pid / stat} и вернуть (cutime + * cstime) * * @param stat *, полученного с помощью {@link #readProcessStat (int)} * / public longgetProcessIdleTime (String [] stat) {return Long.parseLong (stat [16]) + Long.parseLong (stat [17]);} / ** * Возвращает общее использование процессора в процентах.*

* Вызов блокируется на время, указанное в elapse.*

* * @param elapse * время в миллисекундах между чтениями.* @return 12,7 для использования ЦП 12,7% или -1, если значение * недоступно.* / public float syncGetSystemCpuUsage (long elapse) {String stat1 = readSystemStat ();if (stat1 == null) {return -1.f;} пытаться {Thread.sleep (Elapse);} catch (Exception e) {} String stat2 = readSystemStat ();if (stat2 == null) {return -1.f;} return getSystemCpuUsage (stat1, stat2);} / ** * Возвращает использование процессора процессом в процентах.*

* Вызов блокируется на время, указанное в elapse.*

* * @param pid * @param elapse * время в миллисекундах между считываниями.* @return 6.32 для использования ЦП 6.32% или -1, если значение * недоступно.* / 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 ();возврат -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);}}

Существует несколько способов использования этого класса.Вы можете позвонить либо syncGetSystemCpuUsage, либо syncGetProcessCpuUsage, но каждый из них блокирует вызывающий поток.Поскольку общая проблема состоит в том, чтобы контролировать общее использование ЦП и использование ЦП текущего процесса одновременно, я разработал класс, вычисляющий оба из них.Этот класс содержит специальный поток.Управление выводом зависит от реализации, и вам нужно написать собственный код.

Класс можно настроить несколькими способами.Константа CPU_WINDOW определяет глубину чтения, то есть количество миллисекунд между считыванием и вычислением соответствующей загрузки ЦП.CPU_REFRESH_RATE - это время между каждым измерением загрузки процессора.Не устанавливайте CPU_REFRESH_RATE в 0, потому что он приостановит поток после первого чтения.

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);
    }

}
11 голосов
/ 03 августа 2012

Поскольку ОП спрашивал об использовании ЦП и использовании памяти (в принятом ответе указана только техника получения ресурсов процессора), я бы порекомендовал класс ActivityManager и, в частности, принятый ответ на этот вопрос: Как получить текущий Использование памяти в Android?

2 голосов
/ 25 июня 2010

Проверьте класс Debug. http://developer.android.com/reference/android/os/Debug.html т.е. Debug.getNativeHeapAllocatedSize()

У него есть методы для получения используемой собственной кучи, которая используется внешними растровыми изображениями в вашем приложении. Для кучи, которую приложение использует для внутреннего использования, вы можете увидеть это в инструменте DDMS, который поставляется с Android SDK и также доступен через Eclipse.

Собственная куча + куча, как указано в DDMS, составляют общую кучу, которую выделяет ваше приложение.

Для использования процессора, я не уверен, есть ли что-нибудь доступное через API / SDK.

0 голосов
/ 23 февраля 2014

введите терминал Android, а затем вы можете ввести следующие команды: dumpsys cpuinfo

shell@android:/ $ 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
...