Android 查看内存指令

问题

最近在项目中遇到一个 Low on memory 内存过高导致应用退出问题,其中使用了一些内存查看命令,这里做一个记录,错误日志如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
I/ActivityManagerService(  443): Low on memory:
I/ActivityManagerService(  443):   ntv   N     4118 kB: zygote (pid 161) native
I/ActivityManagerService(  443):   ntv   N     2814 kB: surfaceflinger (pid 142) native
I/ActivityManagerService(  443):   ntv   N     1986 kB: logd (pid 136) native
I/ActivityManagerService(  443):   ntv   N     1925 kB: mediaserver (pid 157) native
I/ActivityManagerService(  443):   ntv   N     2749 kB: (Other native)
I/ActivityManagerService(  443):   sys   P    24827 kB: system (pid 443) fixed
I/ActivityManagerService(  443):   pers  P    37707 kB: com.android.systemui (pid 612) fixed
I/ActivityManagerService(  443):   pers  P    13423 kB: com.android.phone (pid 819) fixed
I/ActivityManagerService(  443):   pers  P     8760 kB: com.android.inputmethod.latin (pid 706) fixed
I/ActivityManagerService(  443):   pers  P     5996 kB: android.process.media (pid 575) fixed
I/ActivityManagerService(  443):   pers  P     3577 kB: com.cghs.stresstest (pid 796) fixed
I/ActivityManagerService(  443):   fore  T   153394 kB: com.dlc.huishouxiang (pid 24324) top-activity
I/ActivityManagerService(  443):             261276 kB: TOTAL
I/ActivityManagerService(  443):   MemInfo: 25032 kB slab, 140 kB shmem, 379704 kB vm alloc, 7532 kB page el stack
I/ActivityManagerService(  443):            132 kB buffers, 86556 kB cached, 42500 kB mapped, 180476 kB free
I/ActivityManagerService(  443):   ZRAM: 5652 kB RAM, 520908 kB swap total, 503928 kB swap free
I/ActivityManagerService(  443):   Free RAM: 224664 kB
I/ActivityManagerService(  443):   Used RAM: 677980 kB
I/ActivityManagerService(  443):   Lost RAM: 1158732 kB
I/ActivityManagerService(  443): Start proc 3350:com.android.smspush/u0a43 for service com.android.smspush/.WapPushManager

从日志上 18 ~ 20 行看 Lost RAM 占用太大了,而 Used RAM 占用并不大。

Free RAM:为剩余内存。

Used RAM:为用户态使用总内存。

Lost RAM:为内核态使用内存,比如 OpenGL 纹理内存、GPU 占用内存、图形显示 ION buffer 都包含在 Lost RAM 里,从字面意思是理解它是丢失的内存,也就是说它是操作系统无法解释和正常利用的内存。

其中 Lost RAM = TotalRAM - FreeRAM - UsedRAM 也可以理解为其他内存。

查看内存分配

为了进一步分析,我们接下来使用 adb 命令观察应用内存分配情况。

1
adb shell dumpsys meminfo <package_name|pid> [-d]

-d 标志会打印与 Dalvik 和 ART 内存使用情况相关的更多信息。 pid 可以通过 adb shell ps 查看。

此命令会列出应用的所有当前内存分配,单位为 KB。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
shell@rk3288_box:/ $ dumpsys meminfo 1418
Applications Memory Usage (kB):
Uptime: 2171528 Realtime: 2171528

** MEMINFO in pid 1418 [com.dlc.huishouxiang] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     9647     9556        0        0    12868    11028     1839
  Dalvik Heap    54158    54040        0        0    56026    52280     3746
 Dalvik Other     1096     1096        0        0
        Stack      484      484        0        0
    Other dev        5        0        4        0
     .so mmap     4749      436     2048        0
    .apk mmap      344        0       80        0
    .ttf mmap       33        0       20        0
    .dex mmap    10780        0    10776        0
    .oat mmap     3740        0     1404        0
    .art mmap     1820     1168      144        0
   Other mmap     1096        4      520        0
      Unknown      166      164        0        0
        TOTAL    88118    66948    14996        0    68894    63308     5585

 Objects
               Views:      900         ViewRootImpl:        3
         AppContexts:        5           Activities:        2
              Assets:        2        AssetManagers:        2
       Local Binders:       53        Proxy Binders:       26
       Parcel memory:       11         Parcel count:       44
    Death Recipients:        0      OpenSSL Sockets:        0

 SQL
         MEMORY_USED:      134
  PAGECACHE_OVERFLOW:       37          MALLOC_SIZE:       62

 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4       52            109       73/42/16  /data/data/com.dlc.huishouxiang/databases/bugly_db_

Private CleanPrivate Dirty 是仅供给应用进程使用的内存,这里的内存当应用程序被销毁时大部分会被释放掉。一般来说这一部分内存很重要,这些内存只存在于 RAM 中。

Pss 是对应用程序内存使用情况的一个衡量,包含了进程间的共享账户和共享页面。进程所独有的资源加上按比例分成的共享资源,例如两个进程之间共享页面将为每个进程的 Pss 贡献一半大小。它是衡量进程内存使用情况的一个很重要指标,它最接近于进程的实际使用内存。

Dalvik Heap Dalvik 给你应用程序分配的 RAM 大小,Pss Total 包括所有 Zygote 分配(上面提到过 PSS 通过进程之间共享的内存容量来衡量),Private Dirty 指的是分配给应用程序本身的实际 RAM 大小(不包含共享部分)。

详细内存信息

使用 cat /proc/meminfo 可以查看更加详细的内存信息。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
root@phone:/ # cat /proc/meminfo
MemTotal:        2857.032 kB  //RAM可用的总大小 (即物理总内存减去系统预留和内核二进制代码大小)
MemFree:         1020.708 kB  //RAM未使用的大小
Buffers:           75.104 kB  //用于文件缓冲
Cached:           448.244 kB  //用于高速缓存
SwapCached:             0 kB  //用于swap缓存

Active:           832.900 kB  //活跃使用状态,记录最近使用过的内存,通常不回收用于其它目的
Inactive:         391.128 kB  //非活跃使用状态,记录最近并没有使用过的内存,能够被回收用于其他目的
Active(anon):     700.744 kB  //Active = Active(anon) + Active(file)
Inactive(anon):       228 kB  //Inactive = Inactive(anon) + Inactive(file)
Active(file):     132.156 kB
Inactive(file):   390.900 kB

Unevictable:            0 kB
Mlocked:                0 kB

SwapTotal:        524.284 kB  //swap总大小
SwapFree:         524.284 kB  //swap可用大小
Dirty:                  0 kB  //等待往磁盘回写的大小
Writeback:              0 kB  //正在往磁盘回写的大小

AnonPages:        700.700 kB  //匿名页,用户空间的页表,没有对应的文件
Mapped:           187.096 kB  //文件通过mmap分配的内存,用于map设备、文件或者库
Shmem:               .312 kB

Slab:              91.276 kB  //kernel数据结构的缓存大小,Slab=SReclaimable+SUnreclaim
SReclaimable:      32.484 kB  //可回收的slab的大小
SUnreclaim:        58.792 kB  //不可回收slab的大小

KernelStack:       25.024 kB
PageTables:        23.752 kB  //以最低的页表级
NFS_Unstable:           0 kB  //不稳定页表的大小
Bounce:                 0 kB
WritebackTmp:           0 kB
CommitLimit:     1952.800 kB
Committed_AS:   82204.348 kB   //评估完成的工作量,代表最糟糕case下的值,该值也包含swap内存

VmallocTotal:  251658.176 kB  //总分配的虚拟地址空间
VmallocUsed:      166.648 kB  //已使用的虚拟地址空间
VmallocChunk:  251398.700 kB  //虚拟地址空间可用的最大连续内存块

参考文档:

https://developer.android.com/studio/command-line/dumpsys#meminfo http://gityuan.com/2016/01/02/memory-analysis-command/