adb 查看Android内存的方法

搜集记录手机内存的相关知识、查询方法及输出结果的说明

1. 内存相关知识

名词概念

  • 虚拟内存
    进程空间内的虚拟内存地址,理论上32位cpu一个进程有4GB的虚拟内存可以使用。
  • 物理内存
    就是真正写的到内存条上的,真实地址对进程不可见,由操作系统把虚拟内存地址映射到物理内存地址。
  • Size
    指的就是分配了多少虚拟内存
  • mmap
    一种内存映射文件的方法。
    mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。
    android程序内存被分为2部分:native和dalvik,dalvik就是java堆,普通java对象是在java堆分配,而bitmap是直接在native上分配,对于内存的限制是 native+dalvik 不能超过最大限制。

内存指标概念

  • VSS
    Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
    是单个进程全部可访问的地址空间
  • RSS
    Resident Set Size 实际使用物理内存(包含共享库占用的内存)
    是单个进程实际占用的内存大小,对于单个共享库, 尽管无论多少个进程使用,实际该共享库只会被装入内存一次。
  • PSS
    Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
  • USS
    Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
    USS是一个非常非常有用的数字, 因为它揭示了运行一个特定进程的真实的内存增量大小。如果进程被终止, USS 就是实际被返还给系统的内存大小。
    USS 是针对某个进程开始有可疑内存泄露的情况,进行检测的最佳数字。怀疑某个程序有内存泄露可以查看这个值是否一直有增加。
—— 全称 含义 等价
USS Unique Set Size 物理内存 进程独占的内存
PSS Proportional Set Size 物理内存 PSS= USS+按比例包含共享库
RSS Resident Set size 物理内存 RSS= USS+包含共享库
VSS virtual Set Size 虚拟内存 VSS= RSS+未分配实际物理内存

2. top 命令查看内存信息

该命令常用的相关参数有:
-n xx 获取xx次结果后停止
-m xx 最多显示xx条记录
-d xx 间隔xx秒获取一次内存信息

完整命令:adb shell top -n 1
adb 查看Android内存的方法_第1张图片
第一部分可查看系统整体使用情况,包括任务数、内存、交换区、CPU的使用情况;
第二部分展示了各进程的PID、优先级、内存、CPU等使用情况。

第一部分结果说明

Tasks: 687 total, 2 running, 681 sleeping, 0 stopped, 4 zombie
进程信息:系统进程总数有687 个,运行中的有2 个,休眠中的有 681 个,stoped状态的有0个,zombie状态(僵尸)的有4 个。

Mem: 5.5G total, 5.4G used, 104M free, 6.6M buffers
物理内存: 总量 (5.5G),使用中的 (5.4G),空闲的 (104M),用作内核缓存的内存量 (6.6M)
Swap: 2.7G total, 1.3G used, 1.3G free, 2.3G cached
交换分区(虚拟内存): 总量 (2.7G),已使用的 (1.3G),空闲交换分区总量 (1.3G),缓冲的交换区总量 (2.3G)

800%cpu 10%user 0%nice 20%sys 767%idle 0%iow 0%irq 3%sirq 0%host
cpu状态:
800%cpu – CPU总量
10%user – 表示 CPU 在用户运行的时间百分比,通常用户 CPU 高表示有应用程序比较繁忙。
0%nice – 表示用 nice 修正进程优先级的用户进程执行的 CPU 时间。nice 是一个进程优先级的修正值,如果进程通过它修改了优先级,则会单独统计 CPU 开销。
20%sys – 表示 CPU 在内核态运行的时间百分比(不包括中断),通常内核态 CPU 越低越好,否则表示系统存在某些瓶颈。
767%idle – 空闲CPU百分比
0%iow – IO等待占用CPU的百分比
0%irq – 硬中断(Hardware IRQ)占用CPU的百分比。硬中断是由外设硬件(如键盘控制器、硬件传感器等)发出的,需要有中断控制器参与,特点是快速执行。
0%sirq – 软中断(Software Interrupts)占用CPU的百分比。软中断是由软件程序(如网络收发、定时调度等)发出的中断信号,特点是延迟执行
0%host – ????


交换分区:
缩写为 swap。 swap通过将硬盘空间当成内存来使用,把系统的可用内存变大了 可以把进程暂时不用的数据存储到磁盘中(这个过程为换出),当进程要访问这些数据时,再从磁盘读取这些数据到内存中(这个过程称为换入)。


第二部分结果说明

PID USER PR NI VIRT RES SHR S [%CPU] %MEM TIME+ ARGS
14984 shell 20 0 30M 4.2M 3.1M R 16.6 0.0 0:00.06 top -n 1
1706 system 18 -2 12G 315M 171M S 10.0 5.5 5036:27.8 system_server

PID — 进程id
USER — 进程所有者
PR — 进程优先级
NI — nice值。负值表示高优先级,正值表示低优先级
VIRT — 进程使用的虚拟内存总量
RES — 进程使用的、未被换出的物理内存大小
SHR — 共享内存大小
S — 进程状态
%CPU — 上次更新到现在的CPU时间占用百分比
%MEM — 进程使用的物理内存百分比
TIME+ — 进程使用的CPU时间总计,单位1/100秒
ARGS — 命令名/进程名


进程的几种状态:
R(Running 或 Runnable):可执行状态。表示进程处在CPU的就绪队列中(就绪态或者运行态) D(Disk Sleep):不可中断睡眠状态。这时候进程一般在跟硬件交互,并且在交互的过程中不允许被其他进程打断中断 Z(Zombie):僵尸进程。表示该进程已经结束了,但是其父进程没有回收它的资源(比如进程的描述符、PID等) S:可中断睡眠状态。表示进程因等待某个事件而被系统挂起,当进程等待的事件发生时,就会被唤醒并进入R状态 T(Stopped或Traced):表示进程处于暂停或者跟踪状态 X:进程已经消亡

3. cat /proc/meminfo获取内存整体信息

完整命令:adb shell cat /proc/meminfo

C:\Users\admin>adb shell cat /proc/meminfo
MemTotal: 5768992 kB——物理总内存,约等于5.5G
MemFree: 113780 kB——空闲内存。[MemTotal-MemFree]就是已被用掉的内存。
MemAvailable: 2175400 kB——可用内存(这是系统估算的值)
Buffers: 6004 kB
Cached: 2218924 kB
SwapCached: 63436 kB
Active: 2250044 kB
Inactive: 1424860 kB
Active(anon): 1203240 kB
Inactive(anon): 413032 kB
Active(file): 1046804 kB
Inactive(file): 1011828 kB
Unevictable: 146528 kB
Mlocked: 146528 kB
SwapTotal: 2867196 kB
SwapFree: 1488308 kB
Dirty: 292 kB
Writeback: 0 kB
AnonPages: 1586784 kB
Mapped: 1032380 kB
Shmem: 22572 kB
Slab: 451860 kB
SReclaimable: 135584 kB
SUnreclaim: 316276 kB
KernelStack: 77728 kB
PageTables: 124884 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 5751692 kB
Committed_AS: 135050140 kB
VmallocTotal: 262143936 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
CmaTotal: 1024000 kB
CmaFree: 1304 kB
IonTotalCache: 2688 kB
IonTotalUsed: 199372 kB
Protected: 0 kB
RsvTotalUsed: 335876 kB

MemAvailable:
有些应用程序会根据系统的可用内存大小自动调整内存申请的多少,所以需要一个记录当前可用内存数量的统计值,MemFree并不适用,因为MemFree不能代表全部可用的内存,系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以这部分可回收的内存加上MemFree才是系统可用的内存,即MemAvailable。/proc/meminfo中的MemAvailable是内核使用特定的算法估算出来的,要注意这是一个估计值,并不精确。

4. dumpsys meminfo 获取

获取所有进程的内存信息

命令:adb shell dumpsys meminfo
输出结果示例(行数过多有删减):

C:\Users\admin>adb shell dumpsys meminfo
Applications Memory Usage (in Kilobytes):
Uptime: 1882069276 Realtime: 3623719413

Total PSS by process:
653,521K: com.large.read (pid 8867 / activities)
474,868K: system (pid 1706)
23,634K: com.huawei.nearby (pid 2806)
0K: net.zzuandroidid.ltctsalgebra.ej:system (pid 17453)

Total PSS by OOM adjustment:
1,125,896K: Native
155,363K: dubaid (pid 997)
58,069K: media.codec (pid 1015)
755K: bms_soc (pid 24510)
610K: unrmd (pid 1042)
598K: tombstoned (pid 1055)
574K: usb_port (pid 24507)
561K: octty (pid 1777)
474,868K: System
474,868K: system (pid 1706)
513,831K: Persistent
194,896K: com.android.systemui (pid 15708)
48,848K: com.huawei.HwOPServer (pid 2753)
36,317K: com.huawei.systemserver (pid 2837)
15,843K: com.huawei.android.pushagent.PushService (pid 5438)
943,857K: Foreground
653,521K: com.large.read (pid 8867 / activities)
56,434K: com.huawei.systemmanager:service (pid 2309)
31,775K: net.zzuandroidid.ltctsalgebra.ej (pid 17151)
7,662K: com.android.ujctsoq.tlnctsapple:service (pid 20005)
902,458K: Visible
263,601K: com.kuaishou.nebula (pid 15886 / activities)
118,333K: com.huawei.android.launcher (pid 18613 / activities)
44,855K: com.huawei.lbs (pid 10586)
6,877K: com.huawei.deviceauth (pid 24821)
63,878K: Perceptible
46,208K: com.baidu.input_huawei (pid 7882)
8,854K: com.large.read:push2 (pid 10969)
8,816K: com.large.read:push1 (pid 10936)
30,046K: Previous
30,046K: com.huawei.intelligent (pid 27652)
746,491K: B Services
261,921K: net.zzuandroidid.ltctsalgebra.ej:p4 (pid 17572)
0K: net.zzuandroidid.ltctsalgebra.ej:p3 (pid 17557)
0K: net.zzuandroidid.ltctsalgebra.ej:system (pid 17453)
628,254K: Cached
71,508K: com.huawei.appmarket (pid 7106)
6,486K: com.huawei.android.UEInfoCheck (pid 27379)
6,450K: com.google.android.partnersetup (pid 25103)
6,241K: com.huawei.android.AutoRegSms (pid 27347)

Total PSS by category:
546,147K: Native
469,874K: Dalvik
355,364K: EGL mtrack
338,102K: .dex mmap
281,145K: .so mmap
214,570K: .art mmap
198,395K: .apk mmap
130,212K: Unknown
98,922K: Dalvik Other
87,960K: GL mtrack
63,390K: Other mmap
51,799K: .jar mmap
44,993K: .oat mmap
4,133K: Ashmem
3,520K: Stack
3,069K: Other dev
2,748K: .ttf mmap
8K: Cursor
0K: Gfx dev
0K: Other mtrack

Total RAM: 5,768,992K (status normal)
Free RAM: 1,660,022K ( 628,254K cached pss + 658,856K cached kernel + 372,912K free)
Used RAM: 5,487,693K (4,801,325K used pss + 686,368K kernel)
Lost RAM: 445,693K
ZRAM: 710,812K physical used for 2,412,208K in swap (2,867,196K total swap)
Tuning: 384 (large 512), oom 322,560K, restore limit 107,520K (high-end-gfx)

相关字段说明
划分类型 排序 解释
process PSS 以进程的PSS从大到小依次排序显示,每行显示—个进程;
OOM adjustment PSS 分别显示Native、System、Persistent、Foreground、Visible、Perceptible、Services、Cached每类的进程情况
category PSS 以Dalvik、Native、.art mmap、.dex map等划分的各类进程的总PSS情况
total 总内存、剩余内存、可用内存、其他内存

OOM机制是机器底层的一种强制保鲜,在OOM发生的时候内核会排序强制杀掉进程来保证系统的继续运行,同样这种OOM异常容易发生在低内存机器上,比如512M。

首先系统会根据程序是否是空进程(已经由用户关闭的不带有任何服务和provider的进程),是否有服务,是否有provider,是否为前台进程,来排序,可以输入 adb shell dumpsys meminfo来查看,列出信息中的Total PSS by OOM adjustment:就是系统为程序的OOM排序结果,OOM异常的时候会根据这个表单从下网上杀掉进程释放内存。

获取指定进程(包名)或pid的内存信息

命令:adb shell dumpsys meninfo name/pid
输出结果示例、说明:

C:\Users\admin>adb shell dumpsys meminfo com.large.read
adb 查看Android内存的方法_第2张图片

  • Uptime
    表示启动到现在的时长,不包含休眠的时间,单位毫秒(ms)

  • Realtime
    表示启动到现在的时长,包含休眠的时间,单位毫秒(ms)

  • 行表头说明
    Native Heap:Native代码分配的堆内存,虚拟机和Android框架分配的内存。
    Dalvik Heap:Java对象占据堆内存
    Dalvik Other:类数据结构和索引占据内存
    Stack:栈内存
    Ashmem:不以dalvik- 开头的内存区域,匿名共享内存用来提供共享内存通过分配一个多个进程可以共享的带名称的内存块。
    匿名共享内存(Anonymous Shared Memory-Ashmem。Android匿名共享内存是基于Linux共享内存的,
    都是在tmpfs文件系统上新建文件,并将其映射到不同的进程空间,从而达到共享内存的目的,
    只是,Android在Linux的基础上进行了改造,并借助Binder+fd文件描述符实现了共享内存的传递。
    Other dev:内部driver占用的内存
    .so mmap:C库代码占用的内存
    .jar mmap:java文件代码占用的内存
    .apk mmap:apk代码占用的内存
    .ttf mmap:ttf文件代码占用的内存
    .dex mmap:dex文件代码占用内存。
    类函数的代码和常量占用的内存,
    dex mmap是映射classex.dex文件,Dalvik虚拟机从dex文件加载类信息和字符串常量等。
    Dex文件有索引区和Data区
    .art mmap:
    Other mmap:其它文件占用的内存
    GL mtrack:
    Unknown:
    TOTAL:

  • 列表头说明
    Pss Total:进程占用内存的总和,
    除了Private RAM(Private Dirty、Private Clean)之外,还包括与其他进程共享的内存区域,
    PSS = Private RAM + Shared Dirty RAM ➗ 共享进程数
    Private Dirty:进程私有部分,已释放的内存(数据还没清理)
    Private Clean:进程私有部分,已释放的内存(数据已清理)
    Dirty与clean的区别:clean即干净数据,指该区域的数据与硬盘数据一致,不需要回写即可回收该区域内存。
    而Dirty正好相反,指脏数据,要回收该区域,必须先回写到硬盘。
    SwapPss Dirty:已使用的交换区内存
    一些Android设备确实使用了内存交换,但它们使用的是内存而不是闪存。
    Linux有一个称为ZRAM的特性,它可以压缩页面,然后将它们交换到一个特殊的RAM区域,并在需要时再次解压它们。
    因此,“交换肮脏”中列出的页面很可能是在ZRAM中。
    Heap Size:最大堆可分配的堆内存空间
    Heap Alloc:已分配空间
    Heap Free:剩余空闲空间

adb 查看Android内存的方法_第3张图片

adb 查看Android内存的方法_第4张图片

5. ps 命令

完整命令:adb shell ps

输出结果示例:

adb 查看Android内存的方法_第5张图片

结果的字段说明

USER:进程当前所属的用户
PID:进程ID
PPID:父进程ID
VSZ:进程的虚拟内存大小,以KB为单位
RSS:进程实际占用的内存大小,以KB为单位
WCHAN:进程正在睡眠的内核函数名称,该函数名称是从/root、system.map文件中读取的,
0代表进程处于运行态;否则代表内核函数名称(休眠态)
ADDR:计算机中提供要从[存储器]中取出的下一个指令地址的[寄存器];
S :进程状态
NAME:进程名称

参考资料

dumpsys meminfo内存分析解读(收集整合)
【Android 内存优化】dumpsys meminfo PID 查看单进程内存信息详解
Linux:/proc/meminfo参数详细解释

你可能感兴趣的:(Android性能,android,adb,java)