Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Get CPU usage programmatically (With the cores frequency)

Tags:

android

kotlin

I want to get an approach of CPU usage (of all cores)

Currenlty i can't get the info of "/proc/stat" (since API 27)

so i think of getting the info with the frequency or similar:

Working with all the previous answers i get close to what i want, but not enough

Main Func

  private fun ReadCpu3():String{

        val sb = StringBuffer();
        sb.append("abi: ").append(Build.CPU_ABI).append("\n");

        if (File("/proc/cpuinfo").exists()) {
            try {
                //val br =  BufferedReader(FileReader(File("/proc/cpuinfo")));
                val file = File("/proc/cpuinfo")

                file.bufferedReader().forEachLine {
                    sb.append(it+"\n");
                }

            } catch (e: IOException) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

My results


    processor       : 0
    vendor_id       : GenuineIntel
    cpu family      : 6
    model           : 45
    model name      : Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz
    stepping        : 6
    microcode       : 1561
    cpu MHz         : 600.000
    cache size      : 20480 KB
    physical id     : 0
    siblings        : 16
    core id         : 0
    cpu cores       : 8
    apicid          : 0
    initial apicid  : 0
    fpu             : yes
    fpu_exception   : yes
    cpuid level     : 13
    wp              : yes
    flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid xsaveopt
    bogomips        : 4399.93
    clflush size    : 64
    cache_alignment : 64
    address sizes   : 46 bits physical, 48 bits virtual
    power management:

So i get all the info of the CPU but not the actual load or usage. I do not know if with the current info i can manage to get a proximity of the cpu usage and how exactly.

like image 507
WhySoBizarreCode Avatar asked Aug 31 '25 23:08

WhySoBizarreCode


1 Answers

You should see this SO post here. Basically, you want to use the RandomAccessFile class to parse the /proc/stat file.

EDIT: The above solution won't work for Android O and above. See this link for more information. The Reddit user fornwall filed a report to Google about this and got:

Status: Won't Fix (Intended Behavior) Thank you for filing this bug report.

The removal of /proc/stat was intentional. /proc/stat leaks side channel information about applications which could allow one application to infer the state of other applications on the device. See https://www.cl.cam.ac.uk/~lmrs2/publications/interrupts_pets16.pdf for example.

EDIT2: I've prepared an example (not using CpuStasCollector)

package com.k3.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.regex.Pattern;

public class MainActivity extends AppCompatActivity {

    private static int sLastCpuCoreCount = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textView = findViewById(R.id.txtv);
        textView.setText("");
        for (int i = 0; i < calcCpuCoreCount(); i++) {
            textView.append(takeCurrentCpuFreq(i) +"\n");
        }
    }

    private static int readIntegerFile(String filePath) {

        try {
            final BufferedReader reader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(filePath)), 1000);
            final String line = reader.readLine();
            reader.close();

            return Integer.parseInt(line);
        } catch (Exception e) {
            return 0;
        }
    }

    private static int takeCurrentCpuFreq(int coreIndex) {
        return readIntegerFile("/sys/devices/system/cpu/cpu" + coreIndex + "/cpufreq/scaling_cur_freq");
    }

    public static int calcCpuCoreCount() {

        if (sLastCpuCoreCount >= 1) {
            // キャッシュさせる
            return sLastCpuCoreCount;
        }

        try {
            // Get directory containing CPU info
            final File dir = new File("/sys/devices/system/cpu/");
            // Filter to only list the devices we care about
            final File[] files = dir.listFiles(new FileFilter() {

                public boolean accept(File pathname) {
                    //Check if filename is "cpu", followed by a single digit number
                    if (Pattern.matches("cpu[0-9]", pathname.getName())) {
                        return true;
                    }
                    return false;
                }
            });

            // Return the number of cores (virtual CPU devices)
            sLastCpuCoreCount = files.length;

        } catch(Exception e) {
            sLastCpuCoreCount = Runtime.getRuntime().availableProcessors();
        }

        return sLastCpuCoreCount;
    }
}
like image 98
SnakeException Avatar answered Sep 03 '25 14:09

SnakeException