obsidian/笔记文件/2.笔记/安卓获取内存相关.md
2025-09-22 18:33:09 +08:00

98 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#安卓
#unity/日常积累
移动端存在几个不同的内存获取方式USS、PSS、RSS他们之间的区别
对于USSUnique Set Size计算了TotalPrivateDirty和TotalPrivateClean的总和再转换为MB。USS指的是进程独占的物理内存不包含共享库的部分这部分是正确的。
PSSProportional Set Size是共享内存按比例分配后的值比如三个进程共享一个库每个进程的PSS会加上该库大小的1/3。这也是正确的实现。
RSS实际物理内存占用通过读取/proc/self/status中的VmRSS来获取这是更直接且准确的方式因为系统提供的这个值直接反映了RSS的大小。
![[Pasted image 20250407142019.png]]
逻辑参考:
目前采用最真实的内存获取接口getRSSMemoryMBProc
``` java
//获取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;
}
// 获取 PSSMB
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;
}
// 获取 RSSMB
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]]