You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何精准测试Android应用的CPU、GPU、RAM使用率及系统文件读取方法?

Hey there! Let's walk through how to accurately measure CPU, GPU, and RAM usage for a specific Android app, plus answer your questions about system file access and share practical tips.

1. Measuring RAM Usage for a Specific App

RAM is one of the easiest metrics to capture accurately, thanks to Android's built-in APIs. The most reliable metric is PSS (Proportional Set Size), which represents the actual RAM used by the app (accounting for shared libraries).

Code Example (Non-Root, Works for Own/Other Apps):

import android.app.ActivityManager;
import android.content.Context;
import android.os.Debug;

public class MemoryUtils {
    // Get the PID of the target app
    public static int getAppPid(Context context, String packageName) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo process : am.getRunningAppProcesses()) {
            if (process.processName.equals(packageName)) {
                return process.pid;
            }
        }
        return -1;
    }

    // Get RAM usage in MB
    public static long getAppRamUsage(Context context, int pid) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        Debug.MemoryInfo[] memoryInfos = am.getProcessMemoryInfo(new int[]{pid});
        if (memoryInfos.length > 0) {
            return memoryInfos[0].getTotalPss() / 1024; // Convert KB to MB
        }
        return 0;
    }
}
2. Measuring CPU Usage

CPU measurement is a bit trickier, as it requires calculating delta time between two samples. You can use either system files (pre-Android 10) or official APIs (all versions).

Option 1: Official API (Own App Only)

For your own app, use Debug to get precise process/thread CPU time:

import android.os.Debug;

public class CpuUtils {
    // Get total CPU time used by the app process (nanoseconds)
    public static long getProcessCpuTime() {
        return Debug.getProcessCpuTimeNanos();
    }

    // Calculate usage percentage over a 1-second interval
    public static double calculateCpuUsage() throws InterruptedException {
        long startTime = System.currentTimeMillis();
        long startCpu = getProcessCpuTime();

        Thread.sleep(1000);

        long endTime = System.currentTimeMillis();
        long endCpu = getProcessCpuTime();

        long elapsedTime = endTime - startTime;
        long cpuTimeUsed = endCpu - startCpu;

        // CPU time is in nanoseconds, elapsed time in milliseconds
        return (cpuTimeUsed / 1000000.0) / (elapsedTime * Runtime.getRuntime().availableProcessors()) * 100;
    }
}

Option 2: System Files (Pre-Android 10, Other Apps)

On Android 9 and below, you can read /proc/stat (system CPU total) and /proc/[pid]/stat (app CPU time) to calculate usage:

import java.io.BufferedReader;
import java.io.FileReader;

public class CpuUtils {
    public static double getAppCpuUsage(int pid) throws Exception {
        // Read initial system and app CPU stats
        long initialSystemTotal = getSystemCpuTotal();
        long initialAppTotal = getAppCpuTotal(pid);

        Thread.sleep(1000);

        // Read updated stats
        long updatedSystemTotal = getSystemCpuTotal();
        long updatedAppTotal = getAppCpuTotal(pid);

        long deltaSystem = updatedSystemTotal - initialSystemTotal;
        long deltaApp = updatedAppTotal - initialAppTotal;

        return deltaSystem > 0 ? (deltaApp * 100.0) / deltaSystem : 0;
    }

    private static long getSystemCpuTotal() throws Exception {
        BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"));
        String line = reader.readLine();
        reader.close();
        String[] parts = line.split(" ");
        long total = 0;
        for (int i = 1; i <= 7; i++) total += Long.parseLong(parts[i]);
        return total;
    }

    private static long getAppCpuTotal(int pid) throws Exception {
        BufferedReader reader = new BufferedReader(new FileReader("/proc/" + pid + "/stat"));
        String line = reader.readLine();
        reader.close();
        String[] parts = line.split(" ");
        // utime (14th field) + stime (15th field)
        return Long.parseLong(parts[13]) + Long.parseLong(parts[14]);
    }
}

Note: On Android 10+, system file access to other apps' /proc directories is restricted. Use official APIs or root access for cross-app CPU measurement here.

3. Measuring GPU Usage

GPU metrics are less straightforward, as there's no universal "usage percentage" like CPU. Instead, you measure indirect indicators like frame times, jank rates, or shader execution time.

Official API (API 24+)

Use GraphicsStatsManager to get frame timing data, which reflects GPU load:

import android.app.GraphicsStatsManager;
import android.content.Context;
import android.os.Build;

public class GpuUtils {
    public static void getGpuFrameStats(Context context, String packageName) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            GraphicsStatsManager gsm = (GraphicsStatsManager) context.getSystemService(Context.GRAPHICS_STATS_SERVICE);
            GraphicsStats stats = gsm.getGraphicsStatsForPackage(packageName, 0, System.currentTimeMillis());
            if (stats != null) {
                for (GraphicsStats.WindowStats windowStats : stats.getWindowStats()) {
                    long[] frameTimes = windowStats.getFrameStats().getFramePresentedTimeNanos();
                    // Calculate average frame time, jank rate, etc.
                    long total = 0;
                    for (long time : frameTimes) total += time;
                    double avgFrameTime = total / frameTimes.length / 1000000.0; // Convert to milliseconds
                    System.out.println("Average Frame Time: " + avgFrameTime + "ms");
                }
            }
        }
    }
}

Advanced Tools

For deeper GPU analysis, use Google's Android GPU Inspector (AGI) or manufacturer-specific tools like Qualcomm's Snapdragon Profiler. These give detailed shader, texture, and memory usage data.

4. Can We Get Data by Reading Android System Files?

Yes, but with caveats:

  • RAM: /proc/[pid]/status (look for VmRSS field) gives resident memory, but ActivityManager's API is more reliable (handles shared memory).
  • CPU: /proc/stat and /proc/[pid]/stat work pre-Android 10, but are restricted for other apps on newer versions.
  • GPU: There's no universal system file for GPU usage. GPU data is managed by the hardware abstraction layer (HAL), so official APIs or vendor tools are better.

Key Note: Non-root apps can only read their own /proc files on Android 10+. For other apps, use official APIs or root access.

5. Practical Tutorial & Pro Tips

Step-by-Step Tutorial

  1. Request Permissions: Add <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/> to your manifest, and guide users to enable "Usage Access" in Settings > Security.
  2. Fetch the Target App's PID: Use getAppPid() to get the process ID of the app you want to measure.
  3. Implement Metrics Collection: Use the code examples above to collect RAM, CPU, and GPU data at regular intervals (1-5 seconds is ideal).
  4. Analyze & Visualize: Store data in a database or log file, then plot it to identify usage spikes or bottlenecks.

Pro Tips

  • Validate with Android Studio Profiler: Cross-check your data with the built-in Profiler — it's the most accurate reference for app performance.
  • Avoid Over-Sampling: Frequent collection (e.g., <1s intervals) adds overhead and skews results.
  • Handle API Differences: Use Build.VERSION.SDK_INT checks to support older Android versions.
  • Root Access: If you need system-wide metrics or cross-app data on Android 10+, root access lets you read restricted system files, but official APIs are preferred for non-root apps.
  • GPU Focus: For GPU, prioritize frame time and jank rate over vague "usage percentages" — these directly impact user experience.

内容的提问来源于stack exchange,提问作者Ziyi

火山引擎 最新活动