安卓获取内存相关.md 4.1 KB

#安卓 #unity/日常积累

移动端,存在几个不同的内存获取方式:USS、PSS、RSS,他们之间的区别:

对于USS(Unique Set Size),计算了TotalPrivateDirty和TotalPrivateClean的总和,再转换为MB。USS指的是进程独占的物理内存,不包含共享库的部分,这部分是正确的。

PSS(Proportional Set Size)是共享内存按比例分配后的值,比如三个进程共享一个库,每个进程的PSS会加上该库大小的1/3。这也是正确的实现。

RSS,实际物理内存占用,通过读取/proc/self/status中的VmRSS来获取,这是更直接且准确的方式,因为系统提供的这个值直接反映了RSS的大小。

![[Pasted image 20250407142019.png]]

逻辑参考:

    //获取USS
    public static int getUSSMemoryMB()
    {
        try {
//            if (!hasUsageStatsPermission()) {
//                return -2;
//            }
            int pid = android.os.Process.myPid();
            Activity activity = UnityActivity.getActivity();
            ActivityManager am = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
            Debug.MemoryInfo[] memInfoArray = am.getProcessMemoryInfo(new int[]{pid});
            if (memInfoArray != null && memInfoArray.length > 0)
            {
                Debug.MemoryInfo mi = memInfoArray[0];
                int ussKb = mi.getTotalPrivateDirty() + mi.getTotalPrivateClean();
                return ussKb / 1024; //转MB
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        
        return -1;
    }
    
    // 获取 PSS(MB)
    public static int getPSSMemoryMB() {
        try {
//            if (!hasUsageStatsPermission()) {
//                return -2;
//            }
            int pid = android.os.Process.myPid();
            Activity activity = UnityActivity.getActivity();
            ActivityManager am = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
            Debug.MemoryInfo[] memInfoArray = am.getProcessMemoryInfo(new int[]{pid});
            if (memInfoArray != null && memInfoArray.length > 0) {
                return memInfoArray[0].getTotalPss() / 1024; // 转换为MB
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }
    
    // 获取 RSS(MB)
    public static int getRSSMemoryMBProc() {  
//        long startTime = System.nanoTime(); // 记录开始时间  
        try (BufferedReader br = new BufferedReader(new FileReader("/proc/self/status"))) {  
            String line;  
            while ((line = br.readLine()) != null) {  
                if (line.startsWith("VmRSS:")) {  
                    String[] parts = line.split("\\s+");  
                    int kb = Integer.parseInt(parts[1]);  
                    //                    long duration = (System.nanoTime() - startTime) / 1000; // 微秒耗时  
//                    Log.d("PerfMonitor", "getRSSMemoryMBProc took " + duration + "μs");  
                    return kb / 1024;  
                }  
            }  
            // 如果没有找到VmRSS行也记录耗时  
//            long duration = (System.nanoTime() - startTime) / 1000;  
//            Log.d("PerfMonitor", "getRSSMemoryMBProc (no data) took " + duration + "μs");  
        } catch (Exception e) {  
//            long duration = (System.nanoTime() - startTime) / 1000;  
//            Log.e("PerfMonitor", "getRSSMemoryMBProc failed after " + duration + "μs", e);  
            e.printStackTrace();  
        }  
        return -1;  
    }
    // 获取系统可用内存百分比
    public float getAvailableMemoryPercent() {
        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
        Activity activity = UnityActivity.getActivity();
        ActivityManager am = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
        am.getMemoryInfo(mi);
        return (float)mi.availMem / mi.totalMem * 100;
    }

安卓相关的Manifest.xml文件,也添加一下,权限申请

![[Pasted image 20250407143343.png]]