【Android 内存优化】dumpsys meminfo PID 查看单进程内存信息详解

  • Post author:
  • Post category:其他




1.内存指标

Item 全称 含义 等价
USS Unique Set Size 物理内存 进程独占的内存
PSS Proportional Set Size 物理内存 Pss =Uss+按比例包含共享库
RSS Resient Set Size 物理内存 RSS=USS+包含共享库
VSS Virtual Set Size 虚拟内存 VSS = RSS+未分配实际物理内存

内存的大小关系:

VSS>RSS>=PSS>=USS



在实际分析中,一般是以PSS的内存为准,且也是最符合实际情况的统计值



2.使用

可以使用以下命令记录应用内存在不类型的RAM分配之间的划分情况

adb shell dumpsys meminfo package_name|pid [-d]

-d 标记会输出更多与Dalvik和ART内存占用情况相关的信息。

输出列出了应用当前实时的优点分配信息,以千字节(K)为单位。


  • 获取全局的内存信息


    除了通过上面的方式获取单个进程的内存信息,还可以获取系统整体内存情况。主要场景是用于确认

    单应用多进程的场景,对比下其他进程的当前内存状态

    ,以及

    进程状态

    ,我们要确保进程处理合理的状态。(比如UI进程退到后台要及时退到Cache状态,处于其他状态则要进行优化)
Total PSS by OOM adjustment:
    683,512K: Native
            ...
            854K: dumpsys (pid 19280)
            851K: lmkd (pid 789)
            843K: android.hardware.memtrack@1.0-service (pid 748)
            ...
    396,026K: System
        396,026K: system (pid 1597)
    666,050K: Persistent
        ...
        253,989K: com.android.systemui (pid 2326)
         46,482K: com.huawei.systemserver (pid 2588)
         40,122K: com.huawei.hiview (pid 2543)
         ...
     47,613K: Persistent Service
         34,164K: com.android.bluetooth (pid 20268)
    475,283K: Foreground
        242,908K: com.huawei.android.launcher (pid 10760 / activities)
    351,023K: Visible
        127,248K: com.huawei.hwid.core (pid 28223)
         ...
    117,719K: Perceptible
         95,123K: com.baidu.input_huawei (pid 6331)
         ...
    150,336K: A Services
         82,429K: com.huawei.health:DaemonService (pid 16676)
    196,753K: Previous
        159,932K: com.android.mms (pid 16921 / activities)
        ...
    527,396K: B Services
        164,049K: com.tencent.mm (pid 15990)
        ...
  1,177,708K: Cached
        139,752K: com.huawei.health (pid 18841)
        ...



3.各个属性的详解



3.1 实际样例

以微信举例,如下是一个完整的微信进程的meminfo信息

>adb shell "dumpsys meminfo com.tencent.mm -d"
Applications Memory Usage (in Kilobytes):
Uptime: 539705041 Realtime: 772532637

** MEMINFO in pid 15990 [com.tencent.mm] **
                   Pss  Private  Private  SwapPss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     7697     7688        0    38401    69632    56969    12662
  Dalvik Heap     7223     7220        0     5540    12964     9723     3241
 Dalvik Other     2277     2276        0     4570
        Stack       36       36        0       20
       Ashmem        2        0        0        0
    Other dev       21        0       20        0
     .so mmap    41972     4032    25560       35
    .jar mmap     1245        0        0        0
    .apk mmap    51193        0    13360        0
    .ttf mmap      681        0        0        0
    .dex mmap     5332       28      704      352
    .oat mmap      510        0        0        0
    .art mmap    16366    15940        0    11369
   Other mmap     3672      512      464        0
    GL mtrack     2272     2272        0        0
      Unknown     1848     1848        0     3731
        TOTAL   206365    41852    40108    64018    82596    66692    15903

 App Summary
                       Pss(KB)
                        ------
           Java Heap:    23160
         Native Heap:     7688
                Code:    43684
               Stack:       36
            Graphics:     2272
       Private Other:     5120
              System:   124405

               TOTAL:   206365       TOTAL SWAP PSS:    64018

 Objects
               Views:        0         ViewRootImpl:        0
         AppContexts:        5           Activities:        0
              Assets:        8        AssetManagers:        0
       Local Binders:       77        Proxy Binders:       84
       Parcel memory:       34         Parcel count:      142
    Death Recipients:        8      OpenSSL Sockets:        0
            WebViews:        0

 SQL
         MEMORY_USED:      376
  PAGECACHE_OVERFLOW:       57          MALLOC_SIZE:      117

 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4       28             35         2/18/3  /data/user/0/com.tencent.mm/databases/Scheduler.db
         4      108            109       26/30/15  /data/user/0/com.tencent.mm/databases/google_app_measurement.db

 Asset Allocations
    : 8000K



3.2数据来源



3.2.1 dumpsys 实现逻辑简单介绍

dumpsys的源码结构其实很简单,只有一个dumpsys.cpp

源码路径是:/frameworks/native/cmds/dumpsys/dumpsys.cpp

在其main方法中,先

通过defaultServiceManager()函数获得ServiceManager对象

,然后

根据dumpsys传进来的参数通过函数checkService来找到具体的service

,并执行service的dump方法,达到dumpsys meminfo的目的。



3.2.2 dumpsys meminfo的数据来源

dumpsys meminfo 对应的服务是ActivityManagerService,它从MemBinder类的dump函数开始执行的。总结来说不同类型的Meminfo信息是从不同的位置获取的

在这里插入图片描述

在这里插入图片描述



3.3 属性值详解



3.3.1 主要属性值价绍

我们先从横坐标开始:

序号 字段名称 解释
1 Pss Total
Pss是指实际使用的物理内存

,考虑了在进程之间共享RAM页的情况。

进程独占的RAM页

会直接计入其PSS值,而与

其他进程共享的RAM页

则会按相应比例计入PSS值。例如,两个进程之间共享的RAM页会将其一半的大小 分别计入这两个进程的PSS中,

Pss Total 就是指某一项Pss的总值。
2 Private Dirty 进程私有,是仅分配给应用堆的实际RAM,包含了您自己的分配和zygote分配页,这些分配页自从zygote派生您的应用进程以来已被修改。
3 Private Clean 进程私有的,相对磁盘数据没有使用修改的内存。
4 SwapPss Dirty 一些Android设备确实使用了内存交换,但它们使用的是内存而不是闪存。Linux有一个称为ZRAM的特性,它可以压缩页面,然后将它们交换到一个特殊的RAM区域,并在需要时再次解压它们。因此,“交换肮脏”中列出的页面很可能是在ZRAM中。

纵坐标

序号 属性名 说明
1 Native Heap 在Native Code中使用malloc分配出的内存
2 Dalvik Heap Dalvik 虚拟机(Java 代码)分配的空间,不包括它自身的开销,Dalvik堆中和zygote进程共享的部分算是sharedDirty
3 Dalvik Other 类数据结构和索引占据的内存
3 Stack 堆内存
4 Ashmem 匿名共享内存,此类内存与cache shrinker关联,可以控制cache shrinker在适当时机回收这些共享内存
5 Other dev 内存drvier占用的内存
6 .so mmap 映射的.so(native) 占用的内存
7 .jar mmap Java文件代码占用内存
8 .apk mmap apk代码占用内存
8 .dex mmap 映射的.dex(Dalvik 或ART)代码占用的内存
9 .oat mmap 代码映射占用的RAM量。此映像在所有应用之间共享,不受特定应用影响
10 .art mmap 堆映像占用的RAM量,此映像在所有应用之间共享,不受特定应用影响。尽管ART映射包含Object实例,它仍然不会计入您的堆大小
11 other mmap 其他文件占用的内存
  • 我们某个进程实际的Pss 代码实际内存大小是指横坐标为Pss Total,纵列为Total值(其值等于Pss Total 列+SwapPss Dirty 列的总和),如上所示微信总内存为

    206365

    K.
  • .art mmap 和.dex mmap 列的详细信息可以通过

    showmap pid

    (其他是通过解析

    /proc/pid/smaps

    来得到的结果,详细见

    待整理

    )来获取更详细的信息,meminfo里面的信息其实也是smaps通过后缀名来统计各类的mmap值。



3.3.2 Heap相关

Heap Size Heap Alloc Heap Free
Native Heap Native Code 使用malloc分配的堆内存总大小,从mallinfo usmblks获得,代表最大总共分配空间 从mallinfo uorblks获得,总共已分配空间 从mallinfo fordblks获得,代表总共剩余空闲空间
Dalvik Heap 虚拟机分配的堆内存总大小,从Runtime totalMemory()获得,Dalvik Heap总共的内存大小 Runtime Total Memory()-freeMemory(),Dalvik Heap已分配的内存大小 从RunTime freeMemory获得,Dalvik Heap剩余的内存大小



3.3.3 Objects

  • ViewRootImpl

    进程中当前处于活动状态的根视图数量。每个根视图都与一个窗口关联,因此该值有助于您确实与对话框或者其他窗口有关的内存泄漏
  • AppContexts 和 Activities

    您的进程中当前处于活动状态的应用 Context 和 Activity 对象数量。该值可以帮助您快速确定发生泄漏的 Activity 对象,这些对象由于存在对其的静态引用(比较常见)而无法进行垃圾回收。这些对象往往关联了许多其他分配,因此是查找大型内存泄漏的理想工具。

    当通过Back不断返回退出应用时,Activities值应该等于1


注意


在包含Delvik other 区段的更高平台上,Delvik堆的Pss Total和private Dirty数值不包括Dalvik开销(例如即时编译(JIT和垃圾回收记录)),而更低的版本会在Dalvik中将会其一并列出。



4. 参考资料

https://www.jianshu.com/p/9edfe9d5eb34

https://developer.android.google.cn/studio/command-line/dumpsys#meminfo



版权声明:本文为hl1hl原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。