Android ADB命令之内存统计与分析

一、核心命令总览

工具 / 命令 用途 示例
​adb shell dumpsys meminfo​ 查看设备全局内存状态 ​adb shell dumpsys meminfo​
​adb shell dumpsys meminfo ​ 获取应用详细内存分类统计 ​adb shell dumpsys meminfo com.example.app​
​adb shell top​ 动态查看进程内存和 CPU 占用 ​adb shell top -m 10 -n 1​
​adb shell am dumpheap​ 导出 Java Heap.hprof​文件 ​adb shell am dumpheap com.example.app /data/local/tmp/app.hprof​
​adb pull​ 将 hprof 文件导出至本地分析 ​adb pull /data/local/tmp/app.hprof ./​
​adb shell setprop libc.debug.malloc​ 打开 native 分配追踪 ​adb shell setprop libc.debug.malloc backtrace​
​adb shell am send-trim-memory​ 模拟系统触发内存回收 ​adb shell am send-trim-memory com.example.app TRIM_MEMORY_UI_HIDDEN​

二、核心命令详解与用例

1. adb shell dumpsys meminfo​(全局内存)

作用:查看设备整体内存状态,包括系统剩余内存、应用内存占用排名等。

复制代码
adb shell dumpsys meminfo

关键输出解析:

yaml 复制代码
Total RAM: 5,789,412K (status normal)
 Free RAM: 1,234,567K (  238,456K cached pss +   12,345K kernel)
 Used RAM: 3,456,789K (2,123,456K used pss + 1,333,333K kernel)
 Lost RAM:   987,654K
     ZRAM:   123,456K physical used for   456,789K in swap (500,000K total swap)
字段 说明
Total RAM 设备物理内存总量
Free RAM 可用内存 = 缓存进程内存 + 内核保留内存
Used RAM 已用内存 = 应用实际使用量(PSS) + 内核占用
Lost RAM 内存碎片或无法统计的内存
ZRAM 压缩交换分区使用情况(若启用)

进程内存分类:

csharp 复制代码
Total PSS by OOM adjustment:
    543,052K: Native  # 原生进程
    286,850K: System  # 系统核心进程
    381,177K: Persistent  # 常驻进程(如SystemUI)
    344,152K: Visible  # 可见进程
    245,108K: Perceptible  # 可感知进程(如后台服务)
     91,710K: Backup  # 备份进程
     52,148K: Cached  # 缓存进程

内存类型分布:

csharp 复制代码
Total PSS by :
    510,454K: Native  # Native代码内存
    247,842K: Dalvik  # Java堆内存
    154,596K: .art mmap  # ART运行时
    128,773K: .oat mmap  # AOT编译代码
     20,620K: Gfx dev  # 图形内存

异常状态检测:

  1. Low内存状态:status low​表示系统处于内存紧张状态

  2. ZRAM高使用:695MB/2.3GB的交换空间使用量(压缩比≈3.6倍)

  3. 可疑进程:

    • com.tencent.mm:push (73MB) 占用B Services
    • com.xiaomi.market (85MB) 占用Perceptible

建议脚本:

perl 复制代码
# 监控高内存进程
adb shell dumpsys meminfo | grep -E "K: (Native|System|Persistent|Visible)" -A 3

# 追踪ZRAM变化
watch -n 1 'adb shell dumpsys meminfo | grep "ZRAM"'

2. adb shell dumpsys meminfo ​(应用详情)

作用:获取指定应用的内存详细分布,包括 Java/Native/Graphics 等。

复制代码
adb shell dumpsys meminfo com.example.app

输出示例:

yaml 复制代码
Applications Memory Usage (in Kilobytes):
Uptime: 15123 Realtime: 34253

** MEMINFO in pid 12345 [com.example.myapp] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   -------  -------  -------
  Native Heap     8848     8844        0        0    32768    11234    21534
  Dalvik Heap     7832     7828        0        0    40960    15876    25084
 Dalvik Other     1523     1500        0        0
      Stack         96       96        0        0
     Ashmem          2        0        0        0
    Gfx dev       2492     2488        0        0
      Other dev     28       28        0        0
       .so mmap   4213        8     3324        0
      .apk mmap   1634        0     1234        0
      .ttf mmap     34        0       34        0
      .dex mmap   2090        0     2090        0
     Other mmap    228        0        4        0
    EGL mtrack    1020     1020        0        0
     GL mtrack    1832     1832        0        0
      Unknown     2202     2200        0        0
        TOTAL    43102    32844     6986        0    73728    27110    46618

字段逐项解释

列名 含义
​Pss Total​ Proportional Set Size,总共享后按比例分配的内存大小(关键指标)
​Private Dirty​ 只属于当前进程且被修改的内存页,实际的独占内存
​Private Clean​ 只属于当前进程但未修改的页(可能被回收)
​Swapped Dirty​ 被换出至 swap 空间的脏页数(常见于低内存设备)
​Heap Size​ Java/Dalvik 堆的总大小
​Heap Alloc​ 已分配的堆内存大小
​Heap Free​ 堆中未分配的剩余空间

每一类内存段说明

区域 说明
​Native Heap​ C/C++ 层分配的堆,常由 malloc 或 native 层库使用
​Dalvik Heap​ Java 层内存(对象等)使用情况
​Dalvik Other​ 除了对象外的 Dalvik 使用,比如 Class Metadata
​Stack​ 每个线程的栈内存(通常为 1MB/线程)
​Ashmem​ Android 共享内存机制
​Gfx dev​/GL mtrack​ 与图形相关的内存,比如 UI、OpenGL 缓存等
​.so mmap​ 动态链接库占用的内存
​.apk/.dex/.ttf mmap​ 被 mmap 映射的 APK/Dex/字体文件,不直接进入 Java Heap
​EGL mtrack​ EGL 映射轨迹(GPU 分配追踪)
​Unknown​ 未知来源的内存,常用于估算遗漏项

App Summary 段解释

命令输出后段通常还会出现以下摘要信息:

yaml 复制代码
App Summary
                       Pss(KB)
           Java Heap:  15234
         Native Heap:   8488
        Code:           8352
       Stack:             96
    Graphics:           4002
       Private Other:   1120
       System:          6789
项目 说明
Java Heap Java 对象实际占用的堆内存(已分配)
Native Heap C 层 malloc 等 native 占用
Code ​.so​/.dex​/.apk​mmap 映射的只读代码部分
Stack 线程的栈空间
Graphics 图形缓冲区使用,如 Skia / SurfaceFlinger
Private Other 无法明确归类的私有内存段
System 系统级别共享内存,如 binder、ashmem、zygote 映射等

实战用法与技巧

  1. 快速定位内存占用高的进程
perl 复制代码
adb shell dumpsys meminfo | grep "TOTAL"

输出每个进程的总内存占用,对比谁最占内存。

  1. 结合 top 使用,确认是否导致内存抖动
css 复制代码
adb shell top -n 1 -m 10
adb shell dumpsys meminfo <package_name>

查看是否 Java Heap 或 Native Heap 正在持续上升。

  1. 导出分析数据备份

    adb shell dumpsys meminfo com.example.app > meminfo.txt

保存为本地文本,配合 Git 历史记录查看趋势。


注意事项

  • dumpsys meminfo 的数值仅代表瞬时快照,并非持续记录
  • App 必须处于运行中,否则不会显示完整信息
  • 不支持系统服务(如 system_server)的详细堆栈分布
  • 若需要 GC 后的堆大小,建议先使用:
perl 复制代码
adb shell am send-trim-memory <package_name> TRIM_MEMORY_COMPLETE

推荐组合命令

bash 复制代码
adb shell dumpsys meminfo com.example.app > meminfo.txt
adb shell am dumpheap com.example.app /data/local/tmp/app.hprof
adb pull /data/local/tmp/app.hprof ./app.hprof

3. adb shell top​(实时监控)

新增参数组合建议:

bash 复制代码
# 每2秒刷新一次,按内存排序
adb shell top -o RES -m 5 -d 2
参数 作用
-o 排序字段(RES=内存,%CPU=CPU)
-d 刷新间隔(秒)
-m 显示最大进程数

4. adb shell setprop libc.debug.malloc​(Native内存追踪)

作用:启用Bionic库的malloc调试功能,记录Native代码的内存分配堆栈(需root权限或调试版ROM)

关键参数说明:

参数值 作用
​backtrace​ 记录每次分配的堆栈(默认16帧,可通过backtrace=32​调整)
​log​ 输出分配日志到/data/tombstones/malloc_debug_*​
​program=​ 仅追踪指定进程(如app_process​)
​options="backtrace,guard"​ 组合选项(guard=启用内存边界检查)

典型使用流程:

ini 复制代码
# 1. 启用追踪(需root或adb root)
adb shell stop
adb shell setprop libc.debug.malloc.program com.example.app
adb shell setprop libc.debug.malloc.options backtrace=32
adb shell start

# 2. 复现问题后导出日志
adb pull /data/tombstones/malloc_debug_* ./

# 3. 使用addr2line解析堆栈(需对应so库的调试符号)
arm-linux-androideabi-addr2line -e libnative.so 0x1234 0x5678

输出示例:

bash 复制代码
# malloc_debug_12345.txt 内容片段
@ 0xb6f04567 [com.example.app+0x123456]
  /project/jni/utils.cpp:42 malloc(1024)
@ 0xb6f089ab [com.example.app+0x789abc]
  /project/jni/image_processor.cpp:89 new ImageBuffer()

5. adb shell am send-trim-memory​(内存压力测试)

作用:模拟Android系统在不同内存压力下的回收行为,验证应用的内存管理策略

完整等级表:

等级参数 系统行为 典型触发场景
​TRIM_MEMORY_UI_HIDDEN​ 通知Activity进入后台 用户按Home键
​TRIM_MEMORY_RUNNING_MODERATE​ 释放可缓存资源 系统剩余内存<50%
​TRIM_MEMORY_RUNNING_LOW​ 停止后台服务 系统剩余内存<30%
​TRIM_MEMORY_RUNNING_CRITICAL​ 准备被杀死 系统剩余内存<15%
​TRIM_MEMORY_COMPLETE​ 强制释放所有非关键资源 系统内存严重不足

自动化测试脚本示例:

perl 复制代码
# 模拟内存压力升级过程
for level in UI_HIDDEN RUNNING_MODERATE RUNNING_LOW COMPLETE; do
  adb shell am send-trim-memory com.example.app TRIM_MEMORY_$level
  sleep 3
  adb shell dumpsys meminfo com.example.app | grep "TOTAL PSS"
done

以下是补充 adb shell am dumpheap​ 命令后的完整内容,在保留原有 dumpsys meminfo​ 相关说明的基础上,新增 dumpheap​ 的详细说明:

6. adb shell am dumpheap(堆内存导出到文件)

  1. 命令作用

​am dumpheap​ 是 Android 的 Activity Manager (am) 工具提供的命令,用于将指定进程的 堆内存(Heap) 导出到文件,供后续分析(如检测内存泄漏、对象分配情况等)。导出的文件是标准的 HPROF 格式,可用 Android Studio、MAT(Memory Analyzer Tool)等工具分析。

  1. 命令语法
xml 复制代码
adb shell am dumpheap <pid|process_name> <file_path>
  • <pid|process_name>:目标进程的 PID 或包名(如 com.example.app)。
  • <file_path>:堆转储文件的保存路径(需设备有写入权限)。
  1. 使用示例

示例 1:通过包名导出堆内存

bash 复制代码
adb shell am dumpheap com.example.app /data/local/tmp/heap.hprof

示例 2:通过 PID 导出堆内存

bash 复制代码
adb shell ps -A | grep com.example.app  # 先查找 PID
adb shell am dumpheap 1234 /sdcard/heap.hprof

示例 3:导出系统进程的堆内存(需 root)

arduino 复制代码
adb shell su -c "am dumpheap system_server /data/local/tmp/system_heap.hprof"
  1. 关键注意事项

  2. 文件路径权限:

    • 默认情况下,普通应用无权写入 /data/local/tmp 之外的系统目录。
    • 建议导出到 /sdcard/(需设备有存储权限)或通过 run-as 写入应用私有目录:
    kotlin 复制代码
    adb shell run-as com.example.app am dumpheap com.example.app /data/data/com.example.app/heap.hprof
  3. 进程冻结:

    • 执行 dumpheap 时,目标进程会被短暂冻结(STW,Stop-The-World),可能导致界面卡顿或 ANR(尤其在主线程转储时)。
  4. 文件拉取:

    • 导出的 .hprof​ 文件需通过 adb pull​ 复制到本地分析:

      bash 复制代码
      adb pull /sdcard/heap.hprof ./
  5. HPROF 转换:

    • Android 的 HPROF 是 Dalvik 格式,部分工具(如 MAT)需转换为标准 Java HPROF:

      bash 复制代码
      hprof-conv /path/to/android.hprof /path/to/java.hprof

      (hprof-conv​ 工具位于 Android SDK 的 platform-tools​ 目录)

  6. 实际应用场景

  • 内存泄漏分析:结合 MAT 或 Android Studio Profiler 检查对象引用链。
  • OOM 调试:在崩溃前主动转储堆内存,分析大对象分配。
  • 性能优化:对比不同操作前后的堆状态,定位内存增长点。
  1. 高级用法
  • 触发 GC 后转储(减少噪声):

    xml 复制代码
    adb shell am dumpheap -g <pid> <file_path>

    (-g​ 参数会在转储前触发 GC,但部分设备可能不支持)

  • 自动化脚本:

    bash 复制代码
    adb shell am dumpheap $(pidof com.example.app) /sdcard/heap_$(date +%s).hprof

​dumpsys meminfo​ 与 dumpheap​ 的区别

维度 dumpsys meminfo am dumpheap
数据类型 实时内存统计(PSS/RSS/堆大小等) 完整的堆内存快照(对象引用关系)
用途 快速查看内存占用概况 深度分析内存泄漏或对象分配细节
性能影响 几乎无影响 短暂冻结进程
输出格式 文本 二进制 HPROF 文件

完整工作流程示例

  1. 通过 dumpsys meminfo​ 发现内存异常:

    复制代码
    adb shell dumpsys meminfo com.example.app

    观察到 Dalvik Heap​ 或 Private Dirty​ 持续增长。

  2. 导出堆内存:

    bash 复制代码
    adb shell am dumpheap com.example.app /sdcard/suspicious_heap.hprof
    adb pull /sdcard/suspicious_heap.hprof ./
  3. 分析 HPROF 文件:

    • 使用 Android Studio 的 Memory Profiler 导入文件。
    • 或通过 MAT 查找 Leak Suspects(内存泄漏嫌疑对象)。

通过结合 dumpsys meminfo​ 和 am dumpheap​,可以快速定位内存问题的宏观表现(如总占用过高)和微观细节(如具体泄漏对象)。


三、新增分析流程图

flowchart TD A[发现内存问题] --> B{类型判断} B -->|Java内存泄漏| C[adb dumpheap + MAT分析] B -->|Native泄漏| D[setprop malloc_debug + logcat] B -->|整体偏高| E[dumpsys meminfo分项对比] C --> F[定位Retaining Path] D --> G[分析malloc backtrace] E --> H[优化Graphics/Code内存]

四、实战技巧补充

  1. 批量监控脚本:
bash 复制代码
while true; do
  adb shell dumpsys meminfo com.example.app | grep "TOTAL PSS"
  sleep 5
done
  1. 内存泄漏黄金组合命令
bash 复制代码
# 1. 触发GC后立即dump堆
adb shell am dumpheap -g com.example.app /data/local/tmp/app.hprof

# 2. 同步时间戳便于关联日志
adb shell date +%s > ./dump_time.txt

# 3. 拉取文件并启动MAT分析
adb pull /data/local/tmp/app.hprof ./ && memory-analyzer.sh app.hprof
  1. Native内存分析进阶:
ini 复制代码
# 需要root权限
adb shell stop
adb shell setprop libc.debug.malloc.program app_process
adb shell setprop libc.debug.malloc.options backtrace=32
adb shell start
  1. MAT快捷分析:
  • 使用Leak Suspects报告快速定位问题
  • 按Retained Heap排序查看大对象
  1. Android Studio Profiler联动:
bash 复制代码
# 生成profiler可读的快照
adb shell am profile start com.example.app /data/local/tmp/app.alloc
adb shell am profile stop com.example.app

五、版本差异与兼容性

Android版本 Native追踪支持 Trim Memory等级 关键内存指标
5.0-6.0 需手动编译libc 仅前4个等级 无Swap统计
7.0-8.1 内置malloc_debug 新增BACKGROUND 引入SwapDirty
9.0+ 支持program过滤 新增MODERATE 独立Graphics分类
12.0+ 优化backtrace性能 新增CACHED_RECENT 不可达对象统计

六、附录:常用工具链

  1. MAT (Memory Analyzer Tool):分析.hprof文件
  2. Android Studio Profiler:实时内存可视化
  3. Perfetto:系统级内存追踪
  4. HeapTrack:Linux/Android通用堆分析工具
  5. Glibc Malloc Debug:NDK开发时使用
相关推荐
Dnelic-4 小时前
Android 5G NR 状态类型介绍
android·5g·telephony·connectivity·自学笔记·移动网络数据
吗喽对你问好6 小时前
Android UI 控件详解实践
android·ui
东风西巷9 小时前
X-plore File Manager v4.34.02 修改版:安卓设备上的全能文件管理器
android·网络·软件需求
yzpyzp9 小时前
Android 15中的16KB大页有何优势?
android
安卓开发者9 小时前
Android Room 持久化库:简化数据库操作
android·数据库
程序视点10 小时前
FadCam安卓后台录制神器:2025最全使用指南(开源/免费/息屏录制)
android
游戏开发爱好者812 小时前
没有 Mac,如何上架 iOS App?多项目复用与流程标准化实战分享
android·ios·小程序·https·uni-app·iphone·webview
你过来啊你12 小时前
Android开发中nfc协议分析
android
Auspemak-Derafru13 小时前
安卓上的迷之K_1171477665
android