1 本地调试获取内存信息
1.1 获取系统内存信息
通过在 adb shell 内执行命令 cat /proc/meminfo,获取信息如下:
OP4C72L1:/ $ cat /proc/meminfo
MemTotal: 7800948 kB
MemFree: 227700 kB
MemAvailable: 4981420 kB
Buffers: 12092 kB
Cached: 4694560 kB
SwapCached: 53148 kB
Active: 4018228 kB
Inactive: 1765996 kB
Active(anon): 1021200 kB
Inactive(anon): 269516 kB
Active(file): 2997028 kB
Inactive(file): 1496480 kB
Unevictable: 200428 kB
Mlocked: 200428 kB
SwapTotal: 4194300 kB
SwapFree: 3413924 kB
Dirty: 88 kB
Writeback: 0 kB
AnonPages: 1272280 kB
Mapped: 1445728 kB
Shmem: 15028 kB
KReclaimable: 513568 kB
Slab: 477908 kB
SReclaimable: 194116 kB
SUnreclaim: 283792 kB
KernelStack: 71008 kB
ShadowCallStack: 4441 kB
PageTables: 97700 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 11240496 kB
Committed_AS: 126822724 kB
VmallocTotal: 263061440 kB
VmallocUsed: 141028 kB
VmallocChunk: 0 kB
CmaTotal: 208896 kB
CmaFree: 24264 kB
IonTotalCache: 134756 kB
IonTotalUsed: 108500 kB
GPUTotalUsed: 107708 kB
1.2 获取执行 App 内存信息
主要通过命令dumpsys meminfo <package name>,例如
OP4C72L1:/ $ dumpsys meminfo com.x.x.example
Applications Memory Usage (in Kilobytes):
Uptime: 16468000 Realtime: 39149166
** MEMINFO in pid 3137 [com.shopee.sszrtc.example] **
Pss Private Private SwapPss Rss Heap Heap Heap
Total Dirty Clean Dirty Total Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------
Native Heap 53051 53016 0 22 54372 77824 56613 21210
Dalvik Heap 8292 6656 1592 16 9536 12555 6278 6277
Dalvik Other 4693 3320 8 0 6540
Stack 2396 2396 0 0 2404
Ashmem 8 0 0 0 32
Gfx dev 7168 7160 8 0 7168
Other dev 44 0 44 0 444
.so mmap 28755 768 24144 5 74912
.jar mmap 1992 0 132 0 34692
.apk mmap 491 0 24 0 24076
.ttf mmap 222 0 132 0 600
.dex mmap 16684 16672 0 0 16812
.oat mmap 31 0 0 0 2536
.art mmap 9094 8688 28 0 22536
Other mmap 77 36 0 0 1388
EGL mtrack 61780 61780 0 0 61780
GL mtrack 1152 1152 0 0 1152
Unknown 543 528 4 2 1028
TOTAL 196518 162172 26116 45 196518 90379 62891 27487
App Summary
Pss(KB) Rss(KB)
------ ------
Java Heap: 15372 32072
Native Heap: 53016 54372
Code: 41896 156472
Stack: 2396 2404
Graphics: 70100 70100
Private Other: 5508
System: 8230
Unknown: 6588
TOTAL PSS: 196518 TOTAL RSS: 322008 TOTAL SWAP PSS: 45
Objects
Views: 84 ViewRootImpl: 2
AppContexts: 8 Activities: 2
Assets: 57 AssetManagers: 0
Local Binders: 30 Proxy Binders: 47
Parcel memory: 10 Parcel count: 41
Death Recipients: 5 OpenSSL Sockets: 3
WebViews: 0
SQL
MEMORY_USED: 578
PAGECACHE_OVERFLOW: 92 MALLOC_SIZE: 117
DATABASES
pgsz dbsz Lookaside(b) cache Dbname
4 24 33 2/33/3 /data/user/0/com.shopee.sszrtc.example/databases/hcc
4 20 109 42/73/25 /data/user/0/com.shopee.sszrtc.example/databases/sszrtc
4 20 109 12/43/13 /data/user/0/com.shopee.sszrtc.example/databases/sszrtc
2 线上获取内存信息
2.1 获取系统内存
private long getDevicePhyMemoryInKB() {
ActivityManager manager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
manager.getMemoryInfo(memoryInfo);
long memorySizeInKB = memoryInfo.totalMem / 1024;
Log.i(TAG, "totalMem: " + memorySizeInKB);
return memorySizeInKB;
}
2.2 获取App内存信息
1. ActivityManager.getProcessMemoryInfo(pids: IntArray)
该接口在 Android Q 之后只能获取同 uid 进程的内存数据,而且频率受系统底层限制,默认是 300000 ms (5 min),即5min内多次获取到的是相同的值。可通过命令查看限制时间:
OP4C72L1:/ $ dumpsys activity settings | grep "memory_info"
memory_info_throttle_time=300000
2. Debug.getMemoryInfo(memInfo: Debug.MemoryInfo)
该接口获取到的当前进程内存信息会缺失 graphicis 的数值,其实最后返回的 totalPss 数值是偏小的。网上说,此接口在Android Q 之后可以频繁调用获取到当前进程的内存信息,但经测试,也是被限制了,表现与getProcessMemoryInfo() 一样,在5 min内调用获取到的值依旧不会产生变化。而经过测试,调用 Debug.getPss() 获取到的内存信息是变化的。
综上,个人认为,线上获取App 内存信息可以通过以下方法:
public long getAppMemUsageInKB() {
long memUsageInKB = 0;
try {
long summaryGraphics = 0;
/*
* As start of Android Q, this API is significantly limited, if called faster the limit
* (about 5 min) you will receive the same data as the previous call.
*/
Debug.MemoryInfo[] memInfos = mActivityManager.getProcessMemoryInfo(new int[] {Process.myPid()});
if (memInfos != null && memInfos.length > 0) {
Debug.MemoryInfo memInfo = memInfos[0];
memUsageInKB = memInfo.getTotalPss();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
JSONObject object = new JSONObject(memInfo.getMemoryStats());
Log.d(TAG, "getAppMemUsageInKB, info: " + object);
if (object.has("summary.graphics")) {
summaryGraphics = Integer.parseInt(object.getString("summary.graphics"));
}
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
/* getPss() lack of graphics used memory, need fix up */
memUsageInKB = Debug.getPss() + summaryGraphics;
}
Log.i(TAG, "getAppMemUsageInKB: totalPss = " + memUsageInKB);
} catch (Exception e) {
Log.w(TAG, "getAppMemUsageInKB: ", e);
}
return memUsageInKB;
}
本文介绍了如何在本地和线上获取Android应用的内存信息。本地调试时,通过adb shell命令可获取系统和App内存详情;线上获取则涉及ActivityManager.getProcessMemoryInfo和Debug.getMemoryInfo两个接口,但受到系统限制,5分钟内重复调用可能得到相同结果。建议使用特定方法以获取实时内存数据。
367

被折叠的 条评论
为什么被折叠?



