Android 线上、线下获取内存值的方式。
Android Q 对于线上客户端数据采集有影响,在文中有说明。
案例:cat proc/meminfo 获取手机整体内存信息
dipper:/ $ cat /proc/meminfo MemTotal: 5764820 kB MemFree: 134792 kB MemAvailable: 2791948 kB Buffers: 198508 kB Cached: 2039260 kB SwapCached: 30748 kB Active: 2687728 kB Inactive: 1038232 kB Active(anon): 1203052 kB Inactive(anon): 460412 kB Active(file): 1484676 kB Inactive(file): 577820 kB Unevictable: 161012 kB Mlocked: 161012 kB SwapTotal: 2621436 kB SwapFree: 2022464 kB Dirty: 548 kB Writeback: 0 kB AnonPages: 1643692 kB Mapped: 866444 kB Shmem: 14664 kB Slab: 454188 kB SReclaimable: 198228 kB SUnreclaim: 255960 kB KernelStack: 77744 kB PageTables: 105048 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 5503844 kB Committed_AS: 99980240 kB VmallocTotal: 263061440 kB VmallocUsed: 0 kB VmallocChunk: 0 kB CmaTotal: 204800 kB CmaFree: 156 kB2. dumpsys meminfo
** 通过 dumpsys meminfo -h 可以获取帮助**
dipper:/ $ dumpsys meminfo -h meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process] -a: include all available information for each process. -d: include dalvik details. -c: dump in a compact machine-parseable representation. -s: dump only summary of application memory usage. -S: dump also SwapPss. --oom: only show processes organized by oom adj. --local: only collect details locally, don't call process. --package: interpret process arg as package, dumping all processes that have loaded that package. --checkin: dump data for a checkin --proto: dump data to proto If [process] is specified it can be the name or pid of a specific process to dump.
案例: 获取指定 app 的内存信息
dipper:/ $ dumpsys meminfo -a com.xiaomi.xmsf Applications Memory Usage (in Kilobytes): Uptime: 3335578435 Realtime: 4039602043 ** MEMINFO in pid 7549 [com.xiaomi.xmsf] ** Pss Pss Shared Private Shared Private SwapPss Heap Heap Heap Total Clean Dirty Dirty Clean Clean Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ Native Heap 4136 0 532 4124 0 0 1375 17484 15882 1601 Dalvik Heap 2604 0 284 2596 0 0 63 3740 1870 1870 Dalvik Other 733 0 100 732 0 0 26 Stack 24 0 4 24 0 0 12 Ashmem 0 0 12 0 0 0 0 Other dev 65 0 268 0 0 64 0 .so mmap 405 0 768 44 11348 0 21 .jar mmap 261 0 0 0 10256 0 0 .apk mmap 0 0 0 0 20 0 0 .dex mmap 2448 2444 0 4 4 2444 4 .oat mmap 1205 0 0 0 39116 0 0 .art mmap 1615 4 11488 1348 116 4 202 Other mmap 20 0 32 12 160 0 0 Unknown 756 0 348 748 0 0 326 TOTAL 16301 2448 13836 9632 61020 2512 2029 21224 17752 3471 Dalvik Details .Heap 2112 0 0 2112 0 0 0 .LOS 16 0 0 16 0 0 15 .Zygote 460 0 284 452 0 0 48 .NonMoving 16 0 0 16 0 0 0 .LinearAlloc 313 0 56 312 0 0 22 .GC 304 0 32 304 0 0 4 .IndirectRef 116 0 12 116 0 0 0 .Boot vdex 0 0 0 0 4 0 0 .App dex 1596 1592 0 4 0 1592 4 .App vdex 852 852 0 0 0 852 0 .App art 548 4 0 544 0 4 52 .Boot art 1067 0 11488 804 116 0 150 App Summary Pss(KB) ------ Java Heap: 3948 Native Heap: 4124 Code: 2492 Stack: 24 Graphics: 0 Private Other: 1556 System: 4157 TOTAL: 16301 TOTAL SWAP PSS: 2029 Objects Views: 2 ViewRootImpl: 0 AppContexts: 5 Activities: 0 Assets: 17 AssetManagers: 0 Local Binders: 28 Proxy Binders: 35 Parcel memory: 57 Parcel count: 65 Death Recipients: 1 OpenSSL Sockets: 5 WebViews: 0 SQL MEMORY_USED: 330 PAGECACHE_OVERFLOW: 42 MALLOC_SIZE: 117 DATAbaseS pgsz dbsz Lookaside(b) cache Dbname 4 20 57 2/18/3 /data/user/0/com.xiaomi.xmsf/databases/crash.db 4 16248 21 253/153/2 /data/user/0/com.xiaomi.xmsf/databases/traffic.db线上安卓客户端 1. ActivityManager.getProcessMemoryInfo(pids: IntArray)
在 Android Q 之后只能获取同 uid 进程的内存数据,而且频率受系统底层限制,默认是 300000 ms (5 min)。
可以通过 adb shell settings put global activity_manager_constants ‘memory_info_throttle_time=1000’ 修改底层的频率限制。(需要开启 USB 调试的安全调试模式)
fun getThrottledMemoryInfo(context: Context, pid: Int = myPid()): Debug.MemoryInfo { val memInfo: Debug.MemoryInfo? val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val memInfos: Array2. Debug.getMemoryInfo(memInfo: Debug.MemoryInfo)= manager.getProcessMemoryInfo(IntArray(1) { pid }) memInfo = memInfos[0] return memInfo } private const val SETTINGS_NAME = "activity_manager_constants" private const val MEMORY_INFO_THROTTLE_TIME_KEY_PATTERN = "memory_info_throttle_time=" private const val THROTTLE_VALUE_NAME_PATTERN = "$MEMORY_INFO_THROTTLE_TIME_KEY_PATTERN\d*" // 安卓官方默认的采集间隔是 300 s private const val DEFAULT_THROTTLE_TIME = 300000L // 获取系统的 memory_info_throttle_time 的数值 @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR1) fun getMemoryInfoThrottleTime(context: Context): Long { val resolver = context.contentResolver val constants = Settings.Global.getString(resolver, SETTINGS_NAME) var value = DEFAULT_THROTTLE_TIME if (constants != null) { val regex = Regex(THROTTLE_VALUE_NAME_PATTERN) val find = regex.find(constants) if (find != null && find.groupValues.isNotEmpty()) { val throttle = find.groupValues[0] val valueStr = throttle.substring(MEMORY_INFO_THROTTLE_TIME_KEY_PATTERN.length, throttle.length) value = try { valueStr.toLong() } catch (e: NumberFormatException) { DEFAULT_THROTTLE_TIME } } } return value }
只能获取当进程的内存信息。但在 Android Q 之后依旧可以频繁调用。
会缺失 graphicis 的数值,其实最后返回的 totalPss 数值是偏小的。
fun getDebugMemoryInfo(): Debug.MemoryInfo { val memInfo = Debug.MemoryInfo() Debug.getMemoryInfo(memInfo) return memInfo }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)