内存修改器安卓(Android内存优化工具)
整理下android内存优化常用的几种工具,top命令、adb shell dumpsys meminfo、memory profiler、leakcanary、mat
1. top
top命令是linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况。
查看top命令的用法
$ adb shell top --help
usage: top [-hbq] [-k field,] [-o field,] [-s sort] [-n number] [-m lines] [-d seconds] [-p pid,] [-u user,]
show process activity in real time.
-h show threads
-k fallback sort fields (default -s,-%cpu,-etime,-pid)
-o show fields (def pid,user,pr,ni,virt,res,shr,s,%cpu,%mem,time+,cmdline)
-o add fields (replacing pr,ni,virt,res,shr,s from default)
-s sort by field number (1-x, default 9)
-b batch mode (no tty)
-d delay seconds between each cycle (default 3)
-m maximum number of tasks to show
-n exit after number iterations
-p show these pids
-u show these users
-q quiet (no header lines)
cursor left/right to change sort, up/down move list, space to force
update, r to reverse sort, q to exit.
复制代码
使用top命令显示一次进程信息,以便讲解进程信息中各字段的含义
^[[41;173rtasks: 754 total, 1 running, 753 sleeping, 0 stopped, 0 zombie
mem: 5.5g total, 5.4g used, 165m free, 76m buffers
swap: 2.5g total, 789m used, 1.7g free, 2.4g cached
800%cpu 100%user 3%nice 54%sys 641%idle 0%iow 3%irq 0%sirq 0%host
pid user pr ni virt res shr s[%cpu] %mem time+ args
15962 u0_a894 10 -10 6.6g 187m 76m s 75.6 3.2 8:16.55 asia.bluepay.cl+
785 system -2 -8 325m 13m 7.6m s 29.7 0.2 84:03.91 surfaceflinger
25255 shell 20 0 35m 2.7m 1.6m r 21.6 0.0 0:00.16 top -n 1
739 system -3 -8 177m 3.6m 2.2m s 10.8 0.0 16:00.36 android.hardwar+
16154 u0_i9086 10 -10 1.3g 40m 19m s 5.4 0.6 0:46.18 com.google.andr+
13912 u0_a87 20 0 17g 197m 86m s 5.4 3.4 23:56.88 com.tencent.mm
24789 root rt -2 0 0 0 d 2.7 0.0 0:01.36 [mdss_fb0]
24704 root 20 0 0 0 0 s 2.7 0.0 0:01.20 [kworker/u16:12]
20096 u0_a94 30 10 6.1g 137m 53m s 2.7 2.3 0:31.45 com.xiaomi.mark+
2272 system 18 -2 8.7g 407m 267m s 2.7 7.1 191:11.32 system_server
744 system rt 0 1.3g 1.6m 1.4m s 2.7 0.0 72:22.41 android.hardwar+
442 root rt 0 0 0 0 s 2.7 0.0 5:59.68 [cfinteractive]
291 root -3 0 0 0 0 s 2.7 0.0 5:00.17 [kgsl_worker_th+
10 root 20 0 0 0 0 s 2.7 0.0 1:55.84 [rcuop/0]
7 root 20 0 0 0 0 s 2.7 0.0 2:46.82 [rcu_preempt]
25186 shell 20 0 34m 1.9m 1.4m s 0.0 0.0 0:00.71 logcat -v long +
25181 root 20 0 0 0 0 s 0.0 0.0 0:00.00 [kworker/2:3]
25137 root 20 0 0 0 0 s 0.0 0.0 0:00.00 [kworker/1:3]
25118 system 20 0 5.2g 83m 54m s 0.0 1.4 0:01.05 com.android.set+
24946 u0_a57 20 0 5.1g 60m 37m s 0.0 1.0 0:00.82 com.xiaomi.acco+
复制代码
第 1 行:进程信息
- 总共(total):754个
- 运行中(running)状态:1个
- 休眠(sleeping)状态:753个
- 停止(stopped)状态:0个
- 僵尸(zombie)状态:0个
第 2 行:内存信息
- 5.5g total:物理内存总量
- 5.4g used:使用中的内存量
- 165m free:空闲内存量
- 76m buffers: 缓存的内存量
第 3 行:swap分区信息
- 2.5g total:交换区总量
- 789m used:使用的交换区大小
- 1.7g free:空闲交换区大小
- 2.4g cached:缓冲的交换区大小
内存监控时,可以监控swap交换分区的used,如果这个数值在不断的变化,说明内核在不断进行内存和swap的数据交换,这是内存不够用了。
第 4 行:cpu信息
- 800%cpu:8核cpu
- 100%user:用户进程使用cpu占比
- 3%nice:优先值为负的进程占比
- 54%sys:内核进程使用cpu占比
- 641%idle:除io等待时间以外的其它等待时间占比
- 0%iow:io等待时间占比
- 3%irq:硬中断时间占比
- 0%sirq:软中断时间占比
第 5 行及以下:各进程的状态监控
- pid:进程id
- user:进程所属用户
- pr:进程优先级
- ni:nice值,负值表示高优先级,正值表示低优先级
- virt:进程使用的虚拟内存总量,virt=swap+res
- res:进程使用的、未被换出的物理内存大小,res=code+data
- shr:共享内存大小
- s:进程状态
- %cpu:上次更新到现在的cpu占用时间比
- %mem:使用物理内存占比
- time+:进程时间的cpu时间总计,单位1/100秒
- args:进程名
2. dumpsys meminfo
首先了解下android中最重要的四大内存指标的概念
指标 | 全称 | 含义 | 等价 |
uss | unique set size | 独占物理内存 | 进程独占的内存 |
pss | proportional set size | 实际使用物理内存 | pss = uss + 按比例包含共享库内存 |
rss | resident set size | 实际使用物理内存 | rss = uss + 包含共享库内存 |
vss | virtual set size | 虚拟耗用内存 | vss = 进程占用内存(包括虚拟耗用) + 共享库(包括比例分配部分) |
我们主要使用uss和pss来衡量进程的内存使用情况
dumpsys meminfo命令展示的是系统整体内存情况,内存项按进程进行分类
$ adb shell dumpsys meminfo
applications memory usage (in kilobytes):
uptime: 168829244 realtime: 1465769995
// 根据进程pss占用值从大到小排序
total pss by process:
272,029k: system (pid 2272)
234,043k: com.tencent.mm (pid 13912 / activities)
185,914k: com.android.systemui (pid 13606)
107,294k: com.tencent.mm:appbrand0 (pid 5563)
101,526k: com.tencent.mm:toolsmp (pid 9287)
96,645k: com.miui.home (pid 15116 / activities)
...
// 以oom来划分,会详细列举所有的类别的进程
total pss by oom adjustment:
411,619k: native
62,553k: android.hardware.camera.provider@2.4-service (pid 730)
21,630k: logd (pid 579)
16,179k: surfaceflinger (pid 785)
...
272,029k: system
272,029k: system (pid 2272)
361,942k: persistent
185,914k: com.android.systemui (pid 13606)
37,917k: com.android.phone (pid 2836)
23,510k: com.miui.contentcatcher (pid 3717)
...
36,142k: persistent service
36,142k: com.android.bluetooth (pid 26472)
101,198k: foreground
72,743k: com.miui.securitycenter.remote (pid 4125)
28,455k: com.android.settings (pid 30919 / activities)
338,088k: visible
96,645k: com.miui.home (pid 15116 / activities)
46,939k: com.miui.personalassistant (pid 31043)
36,491k: com.xiaomi.xmsf (pid 4197)
...
47,703k: perceptible
17,826k: com.xiaomi.metoknlp (pid 4477)
10,748k: com.lbe.security.miui (pid 5097)
10,528k: com.xiaomi.location.fused (pid 4563)
8,601k: com.miui.mishare.connectivity (pid 4227)
13,088k: perceptible low
13,088k: com.miui.analytics (pid 19306)
234,043k: backup
234,043k: com.tencent.mm (pid 13912 / activities)
22,028k: a services
22,028k: com.miui.powerkeeper (pid 29762)
198,787k: previous
33,375k: com.android.quicksearchbox (pid 31023)
23,278k: com.google.android.webview:sandboxed_process0:org.chromium.content.app.sandboxedprocessservice0:0 (pid 16154)
171,434k: b services
45,962k: com.tencent.mm:push (pid 14095)
31,514k: com.tencent.mobileqq:msf (pid 12051)
22,691k: com.xiaomi.mi_connect_service (pid 22821)
...
538,062k: cached
107,294k: com.tencent.mm:appbrand0 (pid 5563)
101,526k: com.tencent.mm:toolsmp (pid 9287)
72,112k: com.tencent.mm:tools (pid 9187)
...
// 按内存的类别来进行划分
total pss by category:
692,040k: native
328,722k: dalvik
199,826k: .art mmap
129,981k: .oat mmap
126,624k: .dex mmap
124,509k: unknown
92,666k: .so mmap
68,189k: dalvik other
53,491k: .apk mmap
44,104k: gfx dev
28,099k: other mmap
24,960k: .jar mmap
7,956k: ashmem
3,700k: stack
3,368k: other dev
450k: .ttf mmap
4k: cursor
0k: egl mtrack
0k: gl mtrack
0k: other mtrack
// 手机整体内存使用情况
total ram: 5,862,068k (status normal)
free ram: 3,794,646k ( 538,062k cached pss + 3,189,244k cached kernel + 0k cached ion + 67,340k free)
used ram: 2,657,473k (2,208,101k used pss + 449,372k kernel)
lost ram: 487,987k
zram: 219,996k physical used for 826,852k in swap (2,621,436k total swap)
tuning: 256 (large 512), oom 322,560k, restore limit 107,520k (high-end-gfx)
复制代码
查看单个进程的内存信息,命令如下
adb shell dumpsys meminfo [pid | packagename]
复制代码
我们查看下微信的内存信息
$ adb shell dumpsys meminfo com.tencent.mm
applications memory usage (in kilobytes):
uptime: 169473031 realtime: 1466413783
** meminfo in pid 13912 [com.tencent.mm] **
pss private private swappss heap heap heap
total dirty clean dirty size alloc free
------ ------ ------ ------ ------ ------ ------
native heap 51987 51924 0 61931 159044 139335 19708
dalvik heap 74302 74272 8 2633 209170 184594 24576
dalvik other 10136 10136 0 290
stack 84 84 0 8
ashmem 2 0 0 0
gfx dev 8808 8808 0 0
other dev 156 0 156 0
.so mmap 9984 984 7436 8493
.jar mmap 1428 0 560 0
.apk mmap 2942 0 1008 0
.ttf mmap 1221 0 1064 0
.dex mmap 31302 44 30004 528
.oat mmap 2688 0 232 0
.art mmap 2792 2352 40 3334
other mmap 6932 2752 632 0
unknown 4247 4232 4 7493
total 293721 155588 41144 84710 368214 323929 44284
app summary
pss(kb)
------
java heap: 76664
native heap: 51924
code: 41332
stack: 84
graphics: 8808
private other: 17920
system: 96989
total: 293721 total swap pss: 84710
objects
views: 623 viewrootimpl: 1
appcontexts: 9 activities: 1
assets: 12 assetmanagers: 0
local binders: 198 proxy binders: 183
parcel memory: 46 parcel count: 185
death recipients: 125 openssl sockets: 1
webviews: 0
sql
memory_used: 156
pagecache_overflow: 13 malloc_size: 117
databases
pgsz dbsz lookaside(b) cache dbname
4 28 46 721/26/4 /data/user/0/com.tencent.mm/databases/scheduler.db
asset allocations
: 409k
: 12k
: 1031k
复制代码
- app summary各项指标解读如下,通常我们需要重点关注java heap和native heap的大小,如果持续上升,有可能存在内存泄露。
属性 | 内存组成 |
java heap | dalvik heap的private dirty + .art mmap的private dirty&private clean |
native heap | native heap的private dirty |
code | .so mmap + .jar mmap + .apk mmap + .ttf.mmap + .dex.mmap + .oat mmap的private dirty&private clean |
stack | stack的private dirty |
graphics | gfx dev + egl mtrack + gl mtrack的private dirty&private clean |
- objects中views、activities、appcontexts的异常可以判断有内存泄露,比如刚退出应用,查看activites是否为0,如果不为0,则有activity没有销毁。
3. memory profiler
memory profiler是 android profiler 中的一个组件,实时图表展示应用内存使用量,识别内存泄露和抖动,提供捕获堆转储,强制gc以及跟踪内存分配的能力。
android profiler官方文档
4. leak canary
非常好用的内存泄露检测工具,对于activity/fragment的内存泄露检测非常方便。
square公司开源 官网地址,原理后面单独分析。
5. mat
mat是memory analyzer tool的缩写,是一个非常全面的分析工具,使用相对复杂点。 关于安装和配置有很多很好的文章结束,这里就不单独讲了,后面分析具体案例。
android 内存优化篇 – 使用profile 和 mat 工具进行内存泄漏检测
使用android studio和mat进行内存泄漏分析
内存问题高效分析方法
- 接入leakcanary,监控所有activity和fragment的释放,app所有功能跑一遍,观察是否有抓到内存泄露的地方,分析引用链找到并解决问题,如此反复,直到leakcanary检查不到内存泄露。
- adb shell dumpsys meminfo命令查看退出界面后objects的views和activities数目,特别是退出app后数目为否为0。
- 打开android studio memory profiler,反复打开关闭页面多次,点击gc,如果内存没有恢复到之前的数值,则可能发生了内存泄露。再点击profiler的垃圾桶图标旁的heap dump按钮查看当面内存堆栈情况,按包名找到当前测试的activity,如果存在多份实例,则很可能发生了内存泄露。
- 对于可疑的页面dump出内存快照文件,转换后用mat打开,针对性的分析。
- 观察memory profiler每个页面打开时的内存波峰和抖动情况,针对性分析。
- 开发者选项中打开“不保留后台活动”,app运行一段时间后退到后台,触发gc,dump内存快照。mat分析静态内容是否有可以优化的地方,比如图片缓存、单例、内存缓存等。
上一篇: javascript中如何判断类型汇总