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

一、核心命令总览

工具 / 命令 用途 示例
adb shell dumpsys meminfo 查看设备全局内存状态 adb shell dumpsys meminfo
adb shell dumpsys meminfo <package> 获取应用详细内存分类统计 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 复制代码
adb shell dumpsys meminfo

关键输出解析

java 复制代码
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 压缩交换分区使用情况(若启用)

进程内存分类

java 复制代码
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  # 缓存进程

内存类型分布

java 复制代码
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

建议脚本

adb 复制代码
# 监控高内存进程
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 <package>(应用详情)

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

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

输出示例

java 复制代码
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 段解释

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

plaintext 复制代码
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/.apkmmap 映射的只读代码部分
Stack 线程的栈空间
Graphics 图形缓冲区使用,如 Skia / SurfaceFlinger
Private Other 无法明确归类的私有内存段
System 系统级别共享内存,如 binder、ashmem、zygote 映射等

实战用法与技巧

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

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

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

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

  1. 导出分析数据备份
bash 复制代码
adb shell dumpsys meminfo com.example.app > meminfo.txt

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


注意事项

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

新增参数组合建议:

adb 复制代码
# 每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=<name> 仅追踪指定进程(如app_process
options="backtrace,guard" 组合选项(guard=启用内存边界检查)

典型使用流程:

bash 复制代码
# 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 强制释放所有非关键资源 系统内存严重不足

自动化测试脚本示例:

bash 复制代码
# 模拟内存压力升级过程
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)等工具分析。

2. 命令语法

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

3. 使用示例

示例 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)

bash 复制代码
adb shell su -c "am dumpheap system_server /data/local/tmp/system_heap.hprof"

4. 关键注意事项

  1. 文件路径权限:

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

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

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

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

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

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

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

5. 实际应用场景

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

6. 高级用法

  • 触发 GC 后转储(减少噪声):

    bash 复制代码
    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 meminfodumpheap 的区别

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

完整工作流程示例

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

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

    观察到 Dalvik HeapPrivate 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 meminfoam dumpheap,可以快速定位内存问题的宏观表现(如总占用过高)和微观细节(如具体泄漏对象)。


三、新增分析流程图

Java内存泄漏 Native泄漏 整体偏高 发现内存问题 类型判断 adb dumpheap + MAT分析 setprop malloc_debug + logcat dumpsys meminfo分项对比 定位Retaining Path 分析malloc backtrace 优化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内存分析进阶
bash 复制代码
# 需要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联动
adb 复制代码
# 生成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开发时使用
相关推荐
恋猫de小郭1 小时前
Flutter 里的 Layer 解析,带你了解不一样角度下的 Flutter 渲染逻辑
android·前端·flutter
vivo高启强1 小时前
FD 泄露引发的AGP8 build 失败问题
android
用户2018792831671 小时前
Binder 事务失败(FAILED BINDER TRANSACTION)
android
qq_312920112 小时前
MySQL在Linux环境下的性能调优
linux·mysql·adb
柿蒂2 小时前
Android图片批量添加处理优化:从「30」秒缩短至「4.4」秒
android·android jetpack
拓端研究室3 小时前
专题:2025医药生物行业趋势与投融资研究报告|附90+份报告PDF、原数据表汇总下载
android·开发语言·kotlin
小鱼人爱编程3 小时前
当上组长一年里,我保住了俩下属
android·前端·后端
2501_916013743 小时前
移动端 WebView 调试实战,多平台行为差异排查与统一调试流程
android·ios·小程序·https·uni-app·iphone·webview
liosen7 小时前
【安卓笔记】OOM与内存优化
android·oom·内存优化·内存分析命令·内存分析工具