[小笔记] 如何解读 dumpsys meminfo 的信息

[小笔记] 如何解读 dumpsys meminfo 的信息

通过 adb 命令 adb shell dumpsys meminfo [pakcage name] 能够很简单的看到对应应用的内存使用总体情况,这里面的信息我自己也很容易忘记,我也在网上查找过许多的资料,我发现很多都是写得乱七八糟的,所以我决定自己针对官方的文档和 StackOverflow 中的优秀回答来记录一下。

这是我的应用使用上述命令后展示的信息(不同的 Android 版本,展示的信息可能有区别):

yaml 复制代码
Applications Memory Usage (in Kilobytes):
Uptime: 76374295 Realtime: 369954849

** MEMINFO in pid 15901 [com.phx.waha.dev] **
                   Pss  Private  Private  SwapPss      Rss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty    Total     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------   ------
  Native Heap    77711    77684        0       23    79112   105984    88719    17264
  Dalvik Heap    13888    13788        0       77    15364    17353     8677     8676
 Dalvik Other     3702     2980        0        0     5416                           
        Stack     1908     1908        0        0     1920                           
       Ashmem       55       12        0        0      504                           
    Other dev       48        0       44        0      632                           
     .so mmap    43724     2460    35820       15    79656                           
    .jar mmap     6071        0     3344        0    37364                           
    .apk mmap      698        0      232        0     2288                           
    .ttf mmap     1047        0      264        0     2640                           
    .dex mmap    12702      512    12180        0    13428                           
    .oat mmap       52        0        4        0     1744                           
    .art mmap     8602     7948       92       43    19540                           
   Other mmap      112       40       64        0      908                           
    GL mtrack    67368    67368        0        0    67368                           
      Unknown     1277     1256        8        0     1688                           
        TOTAL   239123   175956    52052      158   329572   123337    97396    25940
 
 App Summary
                       Pss(KB)                        Rss(KB)
                        ------                         ------
           Java Heap:    21828                          34904
         Native Heap:    77684                          79112
                Code:    54836                         138068
               Stack:     1908                           1920
            Graphics:    67368                          67368
       Private Other:     4384
              System:    11115
             Unknown:                                    8200
 
           TOTAL PSS:   239123            TOTAL RSS:   329572       TOTAL SWAP PSS:      158
 
 Objects
               Views:       53         ViewRootImpl:        2
         AppContexts:        7           Activities:        2
              Assets:       28        AssetManagers:        0
       Local Binders:       31        Proxy Binders:       63
       Parcel memory:       14         Parcel count:       55
    Death Recipients:        3      OpenSSL Sockets:        0
            WebViews:        0
 
 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0

我主要分析 MEMINFO 中的横坐标和纵坐标表示意思(有的我也不知道什么意思😂,我就列举下我知道的),其他的部分都很好理解我就不说了。

纵坐标

Pss Total

它的全称是 Proportional Set Size。首先我们要知道我们的应用中内存中的数据可以分为共享的和私有的。比如说系统中所有进程都能够用的资源文件就属于共享的(Shared);我们自己应用的分配的内存,别的应用无法读取的就是私有的(Private)。PSS 就是用来统计内存占用的一种方式,PSS = 私有内存占用 + 共享内存占用 / 共享进程数,通常我们也都使用 PSS 来表示总体的内存占用;还有一种统计内存占用的方式就是 RSSRSS = 私有内存占用 + 共享内存占用,通常我们不会用 RSS 来表示总体的内存占用,只是做一个参考。

Private Dirty / Clean

Private 的内存占用仅供我们自己的进程使用,当进程销毁时系统可以回收 Private 中的绝大部分内存 (我不清楚为什么不是全部🤔),通常最重要的部分就是 Private Dirty 部分,我们应用请求分配的内存也都是这部分,它的占用也是最大的,Android 系统中默认不支持 Linux Swap 机制,它不能保存到磁盘上。所有的 Dalvik 虚拟机和 native 分配的堆内存都是 Private Dirty 的。

官方的文档没有明确表示什么样的内存是 Dirty 的,什么样的内存是 Clean 的,我在 StackOverflow 中看到有人回答了这个问题。

Private Dirty

这部分内存用于我们计算,内存中的内容也是可以修改的,我们自己写的代码分配的内存都是这部分内存。他们也不会被 Swap,当我们的进程被销毁后,这部分内存会被全部回收。

Private Clean

这部分内存从磁盘加载到内存中后就不会修改,比如我们的 dex 字节码和 native 机器码,后续的 .dex mmap.so mmap 行中的内容就能够很容易看到这一点。

Zygote 进程 fork() 后没有修改的数据也是 Clean 的,如果被修改了就会变成 Dirty

SwapPss Dirty

Android 官方文档也没有对这部分内存解释,以下解释都来自 StackOverflow

前面说到 Android 默认不支持 LinuxSwap 机制,这个 Swap 机制是指 Swap 到本地磁盘存储。不懂 Swap 可以看看我之前写的文章:聊聊虚拟内存。这里是类似于 Linux 中的 ZRAM 机制,当内存不足时会把一部分内存压缩交换到 Compressed Page 中,以便节省内存,当需要这部分内存时再把他解压后重新加载到对应的 Page 中。

Rss Total

前面讲 PSS 的时候有讲到,只是一种统计内存的方式:RSS = 私有内存占用 + 共享内存占用

Heap Size

堆的大小。

Heap Alloc

已经分配的堆的大小。

Heap Free

空余的堆大小,计算方式为 Heap Free = Heap Size - Heap Alloc

横坐标

Native Heap

Native 分配的堆内存占用大小,这里有一个让人很费解的点,为什么 Heap Alloc 占用的内存要大于 PSS 呢?是因为这部分内存包含 Zygote fork() 前的共享数据,所以比 PSS 要大,但是为什么比 RSS 还大我就不知道原因了,官方没有讲,可能是他们的计算方式不一样。

Dalvik Heap

Dalvik 虚拟机堆内存占用大小,其他的都是和 Native Heap 类似的。

Dalvik Other

主要是 Dalvik 虚拟机的 JITGC 占用的内存。

Stack

方法栈占用内存。

.so mmap

native 机器码所占内存,我们能够看到大部分的占用是 private clean 的,也就是不修改的私有内存。

.dex mmap / .jar mmap

dex 字节码占用内存和 jar 字节码占用内存,和 .so mmap 类似。

.ttf mmap

字体文件占用内存,感兴趣的可以去了解了解 FreeType

GL mtrack

Open GL 图像相关占用内存,和后面的 Graphics 对应。

还有一些其他的参数就不说了,有的都比较简单,非常直白,有的我也没有搞懂,你可以自己再去查查。

总结

通常我们看内存分析也只是看关键的几个信息,我们先从纵坐标来开始看:PSSPrivate DirtyHeap SizeHeap AllocHeap Free。从横坐标来看:Native HeapDalvik HeapGL mtrack。主要通过以上指标我们就能知道内存大体的占用情况,其他指标也可以参考一下,如果想要看 Heap 中具体的内存占用,还需要借助别的工具,比如说 Android Studio 中的 Profiler

参考文章

官方文档

StackOverflow

相关推荐
vocal21 分钟前
【我的安卓第一课】Android 多线程与异步通信机制(1)
android
顾林海23 分钟前
ViewModel 销毁时机详解
android·面试·android jetpack
恋猫de小郭2 小时前
Google I/O Extended :2025 Flutter 的现状与未来
android·前端·flutter
@Ryan Ding2 小时前
MySQL主从复制与读写分离概述
android·mysql·adb
移动开发者1号3 小时前
Android 同步屏障(SyncBarrier)深度解析与应用实战
android·kotlin
移动开发者1号3 小时前
深入协程调试:协程调试工具与实战
android·kotlin
雨白11 小时前
Jetpack系列(三):Room数据库——从增删改查到数据库平滑升级
android·android jetpack
天若有情67312 小时前
03_性能优化:让软件呼吸更顺畅
计算机·性能优化·软件·发展
双力臂40412 小时前
MyBatis动态SQL进阶:复杂查询与性能优化实战
java·sql·性能优化·mybatis
我就是全世界13 小时前
TensorRT-LLM:大模型推理加速的核心技术与实践优势
人工智能·机器学习·性能优化·大模型·tensorrt-llm