98 lines
4.1 KiB
Markdown
98 lines
4.1 KiB
Markdown
#安卓
|
||
#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]]
|
||
|
||
逻辑参考:
|
||
(目前采用,最真实的内存获取接口: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;
|
||
}
|
||
|
||
// 获取 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]] |