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 shell dumpsys meminfo

关键输出解析

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,654KZRAM:   123,456K physical used for   456,789K in swap (500,000K total swap)
字段说明
Total RAM设备物理内存总量
Free RAM可用内存 = 缓存进程内存 + 内核保留内存
Used RAM已用内存 = 应用实际使用量(PSS) + 内核占用
Lost RAM内存碎片或无法统计的内存
ZRAM压缩交换分区使用情况(若启用)

进程内存分类

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

内存类型分布

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 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 shell dumpsys meminfo com.example.app

输出示例

Applications Memory Usage (in Kilobytes):
Uptime: 15123 Realtime: 34253** MEMINFO in pid 12345 [com.example.myapp] **Pss  Private  Private  Swapped     Heap     Heap     HeapTotal    Dirty    Clean    Dirty     Size    Alloc     Free------   ------   ------   ------   -------  -------  -------Native Heap     8848     8844        0        0    32768    11234    21534Dalvik Heap     7832     7828        0        0    40960    15876    25084Dalvik Other     1523     1500        0        0Stack         96       96        0        0Ashmem          2        0        0        0Gfx dev       2492     2488        0        0Other 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        0Other mmap    228        0        4        0EGL mtrack    1020     1020        0        0GL mtrack    1832     1832        0        0Unknown     2202     2200        0        0TOTAL    43102    32844     6986        0    73728    27110    46618

字段逐项解释

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

每一类内存段说明

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

App Summary 段解释

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

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

实战用法与技巧

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

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

  1. 结合 top 使用,确认是否导致内存抖动
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 后的堆大小,建议先使用:
adb shell am send-trim-memory <package_name> TRIM_MEMORY_COMPLETE

推荐组合命令

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(实时监控)

新增参数组合建议:

# 每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=启用内存边界检查)

典型使用流程:

# 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

输出示例:

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

自动化测试脚本示例:

# 模拟内存压力升级过程
for level in UI_HIDDEN RUNNING_MODERATE RUNNING_LOW COMPLETE; doadb shell am send-trim-memory com.example.app TRIM_MEMORY_$levelsleep 3adb 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. 命令语法

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

3. 使用示例

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

adb shell am dumpheap com.example.app /data/local/tmp/heap.hprof

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

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

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

adb shell su -c "am dumpheap system_server /data/local/tmp/system_heap.hprof"

4. 关键注意事项

  1. 文件路径权限:

    • 默认情况下,普通应用无权写入 /data/local/tmp 之外的系统目录。
    • 建议导出到 /sdcard/(需设备有存储权限)或通过 run-as 写入应用私有目录:
    • 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 复制到本地分析:

      adb pull /sdcard/heap.hprof ./
      
  4. HPROF 转换:

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

      hprof-conv /path/to/android.hprof /path/to/java.hprof
      

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

5. 实际应用场景

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

6. 高级用法

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

    adb shell am dumpheap -g <pid> <file_path>
    

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

  • 自动化脚本

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

dumpsys meminfodumpheap 的区别

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

完整工作流程示例

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

    adb shell dumpsys meminfo com.example.app
    

    观察到 Dalvik HeapPrivate Dirty 持续增长。

  2. 导出堆内存

    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. 批量监控脚本
while true; doadb shell dumpsys meminfo com.example.app | grep "TOTAL PSS"sleep 5
done
  1. 内存泄漏黄金组合命令
# 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内存分析进阶
# 需要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联动
# 生成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开发时使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/916632.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/916632.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法思维进阶 力扣 300.最长递增子序列 暴力搜索 记忆化搜索 DFS 动态规划 C++详细算法解析 每日一题

目录零、题目描述一、为什么这道题值得你深入理解&#xff1f;二、题目拆解&#xff1a;提取核心关键点三、明确思路&#xff1a;从暴力到优化的完整进化3. 进一步优化&#xff1a;动态规划&#xff08;自底向上递推&#xff09;4. 终极优化&#xff1a;贪心 二分查找&#xf…

图解网络-小林coding笔记(持续更新)

大纲 #mermaid-svg-trl6Q4B1uDO1z05w {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-trl6Q4B1uDO1z05w .error-icon{fill:#552222;}#mermaid-svg-trl6Q4B1uDO1z05w .error-text{fill:#552222;stroke:#552222;}#merm…

安宝特案例丨AR+AI+SOP?3大技术融合革新军工航天领域

军工、航空、航天领域存在 “小批量、多品种、依赖人工经验装配”的特性&#xff0c;这长期制约着生产效率与产品质量的提升。 技术融合应用案例 1 Arbigtec 装配效率提升类&#xff1a; 某型导弹制导系统装配&#xff1a;采用 AR 眼镜与 AI 视觉引导系统&#xff0c;200 精…

ip link show 查看/配置网络接口

ip link show&#xff08;或简写为 ip link&#xff09;是 Linux 系统中用于查看和配置网络接口&#xff08;网卡、虚拟接口等&#xff09;的命令&#xff0c;属于 iproute2 工具集的一部分。它是现代 Linux 系统中替代传统 ifconfig 命令的更强大工具。命令详解 基本语法 ip l…

电科金仓新一代数据库一体机:以 “云数据库 - AI 版” 引领 AI 时代数据库变革

前言 AI时代的数据库一体机市场&#xff0c;只能用两个词来形容&#xff1a;高手云集&#xff0c;战况激烈&#xff01; 国际巨头仍在高端市场占据主导地位&#xff0c;但在国产替代的冲击下&#xff0c;也开始另寻突破口&#xff1b;国内科技大厂攻势迅猛&#xff0c;通过开源…

IT运维的365天--033 跨交换机部署没有单独供电口的爱快AP到另一个地方去

前情提要&#xff1a;由于工作需要&#xff0c;领导要求在车间也添加一个无线网络供员工和设备使用&#xff0c;之前公司已经有一个爱快网络供员工使用&#xff0c;且物理隔绝部署在集团办公楼这边了。我一向是不喜欢碰到一个小事就拉一条网线&#xff0c;那样不得搞的跟蜘蛛网…

Flutter开发实战之路由与导航

第5章:路由与导航 在移动应用开发中,页面间的跳转是最基本也是最重要的功能之一。就像我们在现实生活中需要从一个房间走到另一个房间一样,在App中,用户需要在不同的界面间自由切换。Flutter提供了强大而灵活的路由系统来管理这些页面跳转,本章将深入探讨Flutter的路由与…

Android 图像编辑实战指南:从基础操作到进阶效果

在移动应用中&#xff0c;图像编辑功能已成为标配 —— 社交 APP 需要裁剪头像&#xff0c;电商 APP 需要给商品图加水印&#xff0c;工具 APP 需要提供滤镜效果。看似简单的 “裁剪”“缩放” 背后&#xff0c;实则涉及 Bitmap 像素操作、内存管理、性能优化等核心技术。很多开…

Java从入门到精通!第十八天(JDK17安装以及网络编程) 完结篇!!!

三、网络编程1&#xff0e;网络编程概述Java 是 Internet 上的语言&#xff0c;它从语言级上提供了对网络应用程序的支持&#xff0c;程序员能够很容易开发常见的网络应用程序。2&#xff0e;网络的基础&#xff08;1&#xff09;计算机网络把分布在不同地理区域的计算机与专门…

C++ STL常用容器总结(vector, deque, list, map, set)

C STL常用容器总结&#xff08;vector, deque, list, map, set&#xff09;1. vector&#xff08;动态数组&#xff09;特点定义和初始化常用操作遍历方法2. deque&#xff08;双端队列&#xff09;特点定义和初始化常用操作3. list&#xff08;双向链表&#xff09;特点定义和…

智能小车(F103C8T6)RT-THREAD版

前言 前面几章学会了PWM,超声波等&#xff0c;现在刚好结合起来控制智能小车 1&#xff1a;环境 KEIL5.38 RT-THREAD 3.1.3 STM32F103C8T6 2&#xff1a;硬件配件&#xff08;原来网上买的一套&#xff09; STM32F103C8T6 一个 MCU底板 一个 SG90 舵机 一个 红外避障 2个 hc-…

Linux 远程连接与文件传输:从基础到高级配置

Linux 远程连接与文件传输&#xff1a;从基础到高级配置 在 Linux 系统管理中&#xff0c;远程连接和文件传输是核心技能。SSH 协议提供了安全的远程访问方式&#xff0c;而基于 SSH 的 SFTP 和 SCP 则解决了跨服务器文件传输的需求。下面将详细解析 SSH 服务配置、三种远程操作…

17. 如何修改 flex 主轴方向

总结 flex-direction: row | row-reverse | column | column-reverse;一、作用说明 在 Flex 布局中&#xff0c;默认的主轴&#xff08;main axis&#xff09;方向是 水平向右&#xff08;即 row&#xff09;。 通过设置 flex-direction 属性&#xff0c;可以灵活改变主轴的方向…

【Linux】重生之从零开始学习运维之mysql用户管理

mariadb用户管理创建用户create user test210.0.0.% identified by 123456;用户改名rename user test210.0.0.% to test310.0.0.%;用户删除 drop user test310.0.0.%;mysql用户管理创建用户create user test210.0.0.% identified by 123456;用户改名rename user test210.0.0.% …

matlab小计

3.变量命名_哔哩哔哩_bilibili clc 清空页面 文件名&#xff1a;字母开头 clc:清除命令行窗口 clear all&#xff1a;清除工作区变量 编译器里面 %%注释 24 2-4 2*4 4/2 cumsum累计和 312 6123 movsum:滑窗计算数值 eg步长是3 1236 2349 6 9 ... 按列求最大值 先列…

getdents64系统调用及示例

getdents64 函数详解 1. 函数介绍 getdents64 是 Linux 系统中用于读取目录内容的底层系统调用。可以把这个函数想象成一个"目录内容扫描仪"——它能够高效地扫描目录中的所有文件和子目录,就像超市的扫描枪快速读取商品条码一样。 与高级的目录操作函数(如 rea…

HBuilder X打包发布微信小程序

一、获取AppId 二、获取微信小程序AppId 三、发行->微信小程序&#xff0c;调起微信开发者工具 四、点击上传,上传至微信公众平台 五、微信公众平台查看版本管理 完结&#xff01;&#xff01;&#xff01;

docker排查OOM

思路&#xff1a; 1.先从代码程序上排查&#xff0c;线程池创建是否使用ThreadPoolExecutor&#xff0c;线程池各项设置是否合理。 任务对象是否释放&#xff0c;网关是否需要限流。 2.服务器内存大小&#xff0c;cpu使用率&#xff0c;存储空间大小&#xff0c;java程序启动…

Web后端进阶:springboot原理(面试多问)

1.配置优先级 3种配置文件: application.properties server.port8081application.yml server:port: 8082application.yaml server:port: 80822种外部属性的配置(Java系统属性、命令行参数): Java系统属性配置 &#xff08;格式&#xff1a; -Dkeyvalue&#xff09; -Dserver.po…

第十天:字符菱形

每日一道C题&#xff1a;字符菱形 问题&#xff1a;给定一个字符&#xff0c;用它构造一个对角线长5个字符&#xff0c;倾斜放置的菱形。 要求&#xff1a;输入只有一行&#xff0c; 包含一个字符&#xff1b;输出该字符构成的菱形。 最基础的做法&#xff1a; #include <io…