1.adb shell 获取app 进程的pid
adb shell "ps|grep com.xxx包名"
根据某个渠道包,去查询对应的pid,如下所示:
2.通过adb shell 查看设备的java dalvik 堆内存的最大值
执行命令行:
adb shellgetprop dalvik.vm.heapgrowthlimit
若是app进程中java heap(dalvik heap size) 堆内存超过384m 就会抛出oom.
若是app mainfest.xml 中设置了largeHeap=“true”,则app 进程dalvik heap limit 对应512m 限制。
3.查看app进程的物理rss、虚拟内存vss情况:
adb shell procrank(需要手机 root 权限),可忽略该命令。
考虑使用Top 命令行格式:
adb shell top -n 1 |findstr "packageInfo"
以4399渠道包为案例,执行的adb shell top -n 1 |findstr "\ \"
:
或者通过adb shel 查询进程status 方式:
执行命令格式:
adb shellcat /proc/app的pid/status
注意点:在32位(非arm64位)下,app进程中虚拟内存的峰值时3G 多,比较容易触发oom 情况。
4.通过adb shell 命令行查看app进程中内存状况:
格式:
adb shell dumpsys meminfo [pkg/pid]
可以用来查看指定进程包名的内存使用情况
执行adb shell dumpsys meminfo com.minitech.xxxx.m4399
, 可以清楚知道java heap 、native heap、数据库、asset 等 ,内存数值是以KB为单位。
C:\Users\hexingen>adb shell dumpsys meminfo com.minitech.xxx.m4399Applications Memory Usage (in Kilobytes):Uptime: 4282829 Realtime: 4282829** MEMINFO in pid 14622 [com.minitech.miniworld.m4399] ** PssPrivatePrivateSwapPss Heap Heap Heap TotalDirtyCleanDirty SizeAlloc Free------ ------ ------ ------ ------ ------ ------Native Heap 455496 45546880 596992 484213 112777Dalvik Heap263472632800457682938416384 Dalvik Other 6178 617600Stack 3844 384400 Ashmem 5561 509200Other dev 280 280 .so mmap62819 510455760 36.jar mmap4040.apk mmap49281 9980382400.ttf mmap 103107680.dex mmap24272 16242280.oat mmap 86040 39680.art mmap 3794 22245882 Other mmap 6361 20 60760GL mtrack 152964 15296400Unknown795287952801TOTAL 886151 746744 129668 39 642760 513597 129161 App Summary Pss(KB)------ Java Heap:29140 //java 堆所占用的物理内存 Native Heap: 455468 //native 堆所占用的物理内存Code: 138068 Stack: 3844Graphics: 152964 Private Other:96928System: 9739 //app进程中占有物理内存(等于uss+按比列的共享库物理内存) TOTAL: 886151 TOTAL SWAP PSS: 39 Objects // 进程中关键对象情况 ,activity \binder 个数,可看内存泄漏 Views:166 ViewRootImpl:2 AppContexts:5 Activities:4Assets:7AssetManagers:4 Local Binders: 71Proxy Binders: 40 Parcel memory: 40 Parcel count:155Death Recipients:2OpenSSL Sockets:8 SQL MEMORY_USED: 1092PAGECACHE_OVERFLOW:342MALLOC_SIZE: 79 DATABASES //进程中数据库db 打开情况pgsz dbsz Lookaside(b)cacheDbname 4 40480222/96/23/data/user/0/com.minitech.miniworld.m4399/databases/pangle_com.byted.pangle_bd_embed_tea_agent.db 4 24 31 2/20/3/data/user/0/com.minitech.miniworld.m4399/databases/tracker.db 4 52 91 21/29/12/data/user/0/com.minitech.miniworld.m4399/databases/bugly_db_ 4 92200 478/108/25/data/user/0/com.minitech.miniworld.m4399/databases/pangle_com.byted.pangle_ttopensdk.db 4 24 98 1/37/4/data/user/0/com.minitech.miniworld.m4399/databases/pangle_com.byted.pangle_downloader.db 4 20 17 0/30/3/data/user/0/com.minitech.miniworld.m4399/databases/pangle_com.byted.pangle_npth_log.db 4 16 4113/21/6/data/user/0/com.minitech.miniworld.m4399/files/MobSDK/comm/dbs/.dh Asset Allocations//进程中asset 打开情况: 1Kzip:/data/user/0/com.minitech.miniworld.m4399/files/pangle_p/com.byted.pangle/version-4908/apk/base-1.apk:/resources.arsc: 98K
一般情况下,仅需关注 Pss Total 和 Private Dirty 列。 在某些情况下,Private Clean 和 Heap Alloc 列提供的数据也值得关注。
接下来,详细分析下以上的数据:
查看java 堆内存使用:
若是dalvik heap size 超过jvm 阀值(通常384M 或者512M)时,就会触发java heap 导致oom。
查看进程中pss 物理内存使用情况:
- Pss total : 占用的物理内存
- Private Dirty: app进程死亡结束后,系统可回收的arm 物理内存
- Private clean: 当前app进程中已被系统回收的arm 物理内存
若app 进程中pss 物理内存越来越大,系统中arm处理器的可用物理内存越来越少,直到可用物理内存不够分配时,就会触发oom。
查看内存泄漏:
1.AppContexts 和 Activities和ViewRootImpl 表示当前 进程中context 个数和activity个数,根view视图(即phonewindow) 个数据,结合业务查看是否超过当前存在的个数,若是超过,则发生内存泄漏,被静态或者单例类所间接持有。
在java se 中被强引用的对象,是无法被回收的。
更多adb shell dumpsys meminfo 详解:https://blog.51cto.com/u_4387387/6077172。
另外:/proc/pid/maps 和/proc/pid/smaps
通过adb shell 执行需要权限,暂时无法使用。
5.查看当前的手机系统内存情况:
执行adb shell cat /proc/meminfo
,可查看手机处理器内存 ,当前可用的内存
当MemAvailable 可用内存大小越来越少,直到耗尽就触发oom。
6.adb shell 获取内存快照hrop:
执行命令行:
adb shell am dumpheap package包名 /data/local/tmp/xxx.hprof
执行命令行,等待执行完。通过文件 浏览器或者studio的文件管理,找到该文件,双击打开,就可以查看到详细的内存快照。