dumpsys meminfo 是 Android 系统提供的应用级内存分析工具,显示特定应用的详细内存使用情况。与系统级的 /proc/meminfo 不同,这个命令专注于单个应用的内存分解,是应用内存优化的核心工具。
# 方法1: 分析特定应用 (推荐)
adb shell "dumpsys meminfo <package_name>"
# 方法2: 通过 PID 分析
adb shell "dumpsys meminfo <pid>"
# 方法3: 详细模式 (包含更多细节)
adb shell "dumpsys meminfo -d <package_name>"
# 方法4: 所有应用概览
adb shell "dumpsys meminfo -a"
# 方法5: 保存到文件分析
adb shell "dumpsys meminfo <package_name>" > meminfo.txt$ mem -a -d com.android.launcher3
Applications Memory Usage (in Kilobytes):
Uptime: 277172845 Realtime: 423847246
** MEMINFO in pid 21936 [com.android.launcher3] **
- Applications Memory Usage: 应用内存使用报告
- Uptime: 系统运行时间 (毫秒)
- Realtime: 系统实际运行时间 (毫秒)
- pid 21936: 应用进程ID
- [com.android.launcher3]: 应用包名
Pss Pss Shared Private Shared Private Swap Rss Heap Heap Heap
Total Clean Dirty Dirty Clean Clean Dirty Total Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
Native Heap 24482 0 2692 24380 0 0 0 27072 39580 24489 11037
Dalvik Heap 3783 0 4596 3588 0 0 0 8184 28651 4075 24576
Dalvik Other 1755 0 1532 1376 0 0 0 2908
Stack 976 0 12 976 0 0 0 988
Ashmem 2 0 4 0 16 0 0 20
Gfx dev 5884 0 0 5884 0 0 0 5884
Other dev 136 0 216 0 0 136 0 352
.so mmap 3294 168 4280 228 22656 168 0 27332
.jar mmap 1084 8 0 0 11616 8 0 11624
.apk mmap 3048 448 0 0 15468 448 0 15916
.ttf mmap 39 0 0 0 200 0 0 200
.dex mmap 54 0 12 4 128 0 0 144
.oat mmap 1169 4 64 0 9040 4 0 9108
.art mmap 2732 4 16136 2012 156 4 0 18308
Other mmap 490 0 36 8 1776 80 0 1900
EGL mtrack 51348 0 0 51348 0 0 0 51348
GL mtrack 4460 0 0 4460 0 0 0 4460
Unknown 793 0 520 784 0 0 0 1304
TOTAL 105529 632 30100 95048 61056 848 0 187052 68231 28564 35613
- 含义: 🔴 最重要指标 - 应用对系统内存的实际贡献
- 计算: Private + Shared/共享进程数
- 用途: 内存预算分配、性能评估的关键数据
- 示例解读: Native Heap 24482 kB
- 该应用的 Native 内存对系统内存压力贡献了 24.5MB
- 含义: 可以被系统回收的共享内存部分
- 特点: 内存压力时可以丢弃,需要时重新加载
- 示例: .so mmap 168 kB
- 共享库中可回收的代码段
- 含义: 多进程共享且被修改的内存
- 特点: 不能简单回收,需要写回存储
- 问题诊断: 值过大可能有共享内存使用问题
- 含义: 🔴 关键指标 - 应用独占且无法回收的内存
- 重要性: 真正消耗系统内存的部分
- 优化重点: 减少 Private Dirty 是内存优化的核心目标
- 含义: 🟢 最优内存 - 多进程共享且可回收
- 优势: 不占用额外内存,效率最高
- 来源: 系统库、APK文件等只读资源
- 含义: 应用私有但可回收的内存
- 特点: 内存压力时可以丢弃,从文件重新加载
- 含义: 被换出到存储设备的内存
- Android特点: 多数设备显示为0(不使用传统swap)
- 性能影响: 有值表明内存压力大,影响性能
- 含义: 应用当前占用的所有物理内存
- 对比: 通常大于 Pss Total(因为包含完整共享内存)
- Heap Size: 堆的总虚拟大小
- Heap Alloc: 已分配的堆内存
- Heap Free: 可用的堆空间
Native Heap 24482 0 2692 24380 0 0 0 27072 39580 24489 11037
-
Pss Total (24482 kB): Native 内存对系统的贡献
- 评估标准:
- 轻量应用: <20MB
- 普通应用: 20-50MB
- 重型应用: 50-100MB
- 异常: >100MB
- 评估标准:
-
Private Dirty (24380 kB): 真正的 Native 内存消耗
- 来源: C/C++ malloc/new 分配
- 问题诊断: 接近 Pss Total 说明几乎全是私有内存
-
Heap Size (39580 kB): Native 堆总空间
- 对比: Size > Alloc 说明有预留空间
- 效率: Alloc/Size 比例反映堆利用率
-
Heap Alloc (24489 kB): 实际分配的 Native 内存
-
Heap Free (11037 kB): 可用的 Native 堆空间
# 检查 Native 内存泄漏
# 1. 对比操作前后的 Native Heap 变化
adb shell "dumpsys meminfo <package>" | grep "Native Heap"
# 2. 使用详细模式查看 Native 分类
adb shell "dumpsys meminfo -d <package>"
# 3. Native 内存调试工具
# - AddressSanitizer (ASan)
# - Malloc debug hooks
# - Valgrind (模拟器)优化建议:
- 检查 JNI 代码中的内存分配和释放
- 审查第三方 Native 库的内存使用
- 使用对象池减少频繁的 malloc/free
Dalvik Heap 3783 0 4596 3588 0 0 0 8184 28651 4075 24576
-
Pss Total (3783 kB): Java 堆内存贡献
- 评估标准:
- 轻量应用: <30MB
- 普通应用: 30-80MB
- 重型应用: 80-200MB
- 异常: >200MB
- 评估标准:
-
Shared Dirty (4596 kB): 共享的 Java 堆内存
- 来源: Zygote 进程共享的系统类
- 特点: 比 Private Dirty 大说明有效利用了共享
-
Private Dirty (3588 kB): 应用独有的 Java 对象
- 重要性: 真正的 Java 内存使用
- 优化重点: 减少对象创建和内存泄漏
-
Heap Size (28651 kB): Java 堆的最大可用空间
-
Heap Alloc (4075 kB): 当前分配的 Java 内存
-
Heap Free (24576 kB): 可用的 Java 堆空间
# Java 堆利用率
heap_utilization = Heap Alloc / Heap Size * 100%
# 示例: 4075 / 28651 * 100% = 14.2%
# 评估标准:
# - <30%: 堆空间充足
# - 30-70%: 正常使用
# - 70-90%: 内存紧张,可能频繁 GC
# - >90%: 内存不足,性能受影响# 1. 一键全景分析(推荐)
python3 analyze.py live --package <package>
# 2. HPROF 分析 Java 对象
python3 tools/hprof_dumper.py -pkg <package>
python3 tools/hprof_parser.py -f <hprof_file>
# 3. GC 监控
adb shell "dumpsys gfxinfo <package>"
# 4. 内存泄漏检测
# - LeakCanary 自动检测
# - MAT (Memory Analyzer Tool) 分析 Dalvik Other 1755 0 1532 1376 0 0 0 2908
- LinearAlloc: 类和方法的线性分配器
- GC: 垃圾收集器开销
- JIT: 即时编译器缓存
- 间接引用表: JNI 全局引用管理
- 过大原因:
- 加载了过多类
- JNI 引用泄漏
- JIT 编译缓存过大
Gfx dev 5884 0 0 5884 0 0 0 5884
EGL mtrack 51348 0 0 51348 0 0 0 51348
GL mtrack 4460 0 0 4460 0 0 0 4460
- Gfx dev (5884 kB): GPU 设备直接内存
- EGL mtrack (51348 kB): EGL 图形内存追踪
- GL mtrack (4460 kB): OpenGL 内存追踪
Total Graphics = Gfx dev + EGL mtrack + GL mtrack
= 5884 + 51348 + 4460 = 61692 kB (约60MB)- 普通应用: <30MB
- 图形密集: 30-100MB
- 游戏应用: 100-300MB
- 异常: >300MB
// 1. 位图优化
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565; // 减少内存
options.inSampleSize = 2; // 缩放
// 2. 及时回收
if (bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
}
// 3. GPU 资源管理
// 及时释放纹理、缓冲区等 GPU 资源 .so mmap 3294 168 4280 228 22656 168 0 27332
- 高 Shared Clean (22656 kB): 系统库被多进程共享
- 低 Pss (3294 kB): 高效的内存共享
- 优化: 体现了共享库的内存效率
.apk mmap 3048 448 0 0 15468 448 0 15916
- Shared Clean (15468 kB): APK 代码被多组件共享
- Private Clean (448 kB): 应用特有的 APK 部分
.art mmap 2732 4 16136 2012 156 4 0 18308
- 高 Shared Dirty (16136 kB): ART 编译代码的共享
- 性能优化: 预编译代码提升执行效率
Dalvik Details
.Heap 2500 0 0 2500 0 0 0 2500
.LOS 327 0 1616 260 0 0 0 1876
.Zygote 656 0 2980 528 0 0 0 3508
.NonMoving 300 0 0 300 0 0 0 300
.LinearAlloc 1145 0 756 1116 0 0 0 1872
.GC 122 0 56 120 0 0 0 176
.ZygoteJIT 0 0 16 0 0 0 0 16
.AppJIT 368 0 696 20 0 0 0 716
.IndirectRef 120 0 8 120 0 0 0 128
.Boot vdex 0 0 0 0 16 0 0 16
.App dex 52 0 12 4 108 0 0 124
.App vdex 2 0 0 0 4 0 0 4
.App art 348 4 0 344 0 4 0 348
.Boot art 2384 0 16136 1668 156 0 0 17960
- 2500 kB: 主要的 Java 对象存储区域
- 全为 Private: 说明是应用独有的对象实例
- 327 kB: 大对象空间(>12KB 对象)
- 用途: 大数组、位图等对象
- Shared Dirty (1616 kB): 部分大对象可能被共享
- 656 kB PSS: Zygote 进程共享内存的分摊
- 高 Shared Dirty (2980 kB): 系统类的共享
- 优势: 多应用共享,节省系统内存
- 300 kB: Class 对象、JNI 全局引用
- 特点: GC 时不移动这些对象
- 稳定性: 相对稳定,缓慢增长
- 1145 kB: 类加载时的辅助数据
- 版本: 主要在较老的 Android 版本中使用
- 122 kB: GC 算法的内存开销
- 正常: 少量开销是正常的
- .ZygoteJIT (0 kB): Zygote 进程的 JIT 缓存
- .AppJIT (368 kB): 应用的 JIT 编译缓存
- 优化: 热点代码的运行时编译
- 120 kB: JNI 引用管理表
- 问题: 异常增长可能有 JNI 引用泄漏
- .App dex (52 kB): 应用 DEX 字节码
- .App vdex (2 kB): DEX 验证文件
- .App art (348 kB): 应用 ART 编译代码
- .Boot art (2384 kB): 系统框架 ART 代码
App Summary
Pss(KB) Rss(KB)
------ ------
Java Heap: 5604 26492
Native Heap: 24380 27072
Code: 880 65056
Stack: 976 988
Graphics: 61692 61692
Private Other: 2364
System: 9633
Unknown: 5752
TOTAL PSS: 105529 TOTAL RSS: 187052 TOTAL SWAP (KB): 0
- 计算: Dalvik Heap + 部分 Dalvik Other
- 占比: 5604/105529 = 5.3%
- 评估: Java 内存占比较低,应用可能偏向 Native 或图形
- 占比: 24380/105529 = 23.1%
- 对比: 与 Java Heap 比例约 4:1
- 分析: Native 内存使用较多,需关注 C/C++ 代码
- 含义: 代码段内存(.so、.dex、.oat 等)
- 特点: 大部分为共享内存,PSS 较小
- 占比: 61692/105529 = 58.5%
- 分析: 图形内存占比过半,是优化重点
- 问题: 可能有大量位图或 GPU 资源
# 理想的内存分布 (参考)
Java Heap: 30-50% (当前: 5.3%)
Native Heap: 20-30% (当前: 23.1%)
Graphics: 10-30% (当前: 58.5%)
Code: 5-15% (当前: 0.8%)
Other: 5-20% (当前: 12.3%)- 🔴 图形内存过高: 需要重点优化
- 🟡 Java 内存偏低: 可能过度依赖 Native
- 🟢 代码内存合理: 共享效率高
Objects
Views: 114 ViewRootImpl: 1
AppContexts: 9 Activities: 1
Assets: 7 AssetManagers: 0
Local Binders: 39 Proxy Binders: 41
Parcel memory: 17 Parcel count: 75
Death Recipients: 1 OpenSSL Sockets: 0
WebViews: 0
- Views (114): View 对象数量
- 评估: 数量合理,大型界面可能更多
- 优化: 减少不必要的 View 层次
- ViewRootImpl (1): 根视图实现
- 正常: 通常对应 Activity 数量
- AppContexts (9): 应用上下文数量
- 来源: Application、Service、Activity 等
- 问题: 过多可能有 Context 泄漏
- Activities (1): Activity 实例数
- 正常: 对应当前活跃的 Activity
- Assets (7): 资源文件句柄
- AssetManagers (0): 资源管理器实例
- Local Binders (39): 本地 Binder 对象
- Proxy Binders (41): 代理 Binder 对象
- Parcel (17/75): 序列化对象内存/数量
- OpenSSL Sockets (0): SSL 连接数
- WebViews (0): WebView 组件数
# 监控对象数量变化
# 1. 获取基准数据
adb shell "dumpsys meminfo <package>" | grep -A 15 "Objects"
# 2. 执行操作后再次检测
# 3. 对比对象数量变化
# 重点关注:
# - Activities > 2: 可能有 Activity 泄漏
# - Views 持续增长: 可能有 View 泄漏
# - AppContexts 异常多: Context 泄漏 SQL
MEMORY_USED: 217
PAGECACHE_OVERFLOW: 36 MALLOC_SIZE: 46
DATABASES
pgsz dbsz Lookaside(b) cache Dbname
4 400 64 171/60/5 /data/user/0/com.android.launcher3/databases/app_icons.db
4 56 87 26/61/6 /data/user/0/com.android.launcher3/databases/launcher.db
4 16 27 36/61/2 /data/user/0/com.android.launcher3/databases/widgetpreviews.db
- MEMORY_USED (217 KB): SQLite 总内存使用
- PAGECACHE_OVERFLOW (36 KB): 页面缓存溢出
- MALLOC_SIZE (46 KB): SQLite malloc 分配
- pgsz: 页面大小 (KB)
- dbsz: 数据库大小 (KB)
- Lookaside(b): 预分配内存池 (bytes)
- cache: 缓存统计 (使用/最大/最小)
app_icons.db:
- 大小: 400 KB (最大)
- 缓存: 171/60/5 (缓存使用较多)
- 用途: 应用图标缓存
launcher.db:
- 大小: 56 KB
- 缓存: 26/61/6
- 用途: 启动器配置数据
widgetpreviews.db:
- 大小: 16 KB (最小)
- 缓存: 36/61/2
- 用途: 小部件预览缓存
-- 1. 定期清理过期数据
DELETE FROM cache_table WHERE timestamp < ?
-- 2. 优化查询,减少内存使用
SELECT * FROM table LIMIT 100 -- 避免大结果集
-- 3. 合理设置缓存大小
PRAGMA cache_size = 2000; -- 设置页面缓存
-- 4. 使用 WAL 模式提升并发
PRAGMA journal_mode = WAL;# 症状: Dalvik Heap 持续增长
# 前: Dalvik Heap 3783 kB
# 后: Dalvik Heap 8756 kB (增长 4973 kB)
# 诊断流程:
# 1. 对比操作前后的 meminfo
# 2. 检查 Heap Alloc 和 Objects 数量变化
# 3. 使用 HPROF 分析具体对象# 症状: Native Heap 持续增长
# 前: Native Heap 24482 kB
# 后: Native Heap 35672 kB (增长 11190 kB)
# 诊断工具:
# - AddressSanitizer
# - Malloc debug hooks
# - Native 内存 profiler# 症状: Graphics 内存异常增长
# EGL mtrack 51348 kB → 85672 kB
# 常见原因:
# - 位图未及时回收
# - GPU 资源未释放
# - 纹理内存积累Graphics: 61692 kB (58.5% of total)
# 问题: 图形内存占比过高
# 正常: 应该在 10-30%诊断步骤:
# 1. 分解图形内存来源
Gfx dev: 5884 kB (GPU 设备内存)
EGL mtrack: 51348 kB (EGL 图形内存)
GL mtrack: 4460 kB (OpenGL 内存)
# 2. 重点分析 EGL mtrack (最大占用)
# - 检查位图加载和缓存策略
# - 分析纹理使用情况
# - 查看 GPU 资源管理
# 3. 使用图形调试工具
adb shell "dumpsys gfxinfo <package> framestats"# 如果 Native Heap > 50% 总内存
# 可能问题:
# - C/C++ 内存分配过多
# - JNI 使用不当
# - 第三方库内存问题# 可能原因:
# - 应用主要逻辑在 Native 层
# - 过度依赖 C/C++ 实现
# - 图形渲染占主导
# 评估:
# - 检查架构设计是否合理
# - 考虑 Java/Native 平衡# 正常: Activities: 1
# 异常: Activities: 3+ (多个 Activity 实例)
# 常见原因:
# - Static 引用持有 Activity
# - Handler 内部类未正确处理
# - 监听器未注销# 监控 Views 数量变化
# 前: Views: 114
# 后: Views: 245 (操作后显著增长)
# 诊断:
# - 检查 View 是否正确移除
# - 分析 View 层次结构
# - 查看 ViewHolder 复用# 异常: AppContexts: 15+ (过多上下文)
# 正常: 通常 < 10
# 检查:
# - 是否有 static 引用 Context
# - Service 是否正确停止
# - 监听器是否使用 ApplicationContext- 总 PSS: <80MB
- Java Heap: 20-40% 总内存
- Native Heap: 20-40% 总内存
- Graphics: <20% 总内存
- Heap 利用率: 30-70%
- 总 PSS: 80-150MB
- Graphics: 20-40% 总内存
- 对象数量: 在合理范围
- 无明显内存泄漏
- 总 PSS: 150-250MB
- Graphics: 40-60% 总内存
- Heap 利用率: >80%
- 对象数量: 偏多
- 总 PSS: >250MB
- Graphics: >60% 总内存
- 明显内存泄漏: Activity/View 数量异常
- 频繁 OOM: 内存不足
#!/bin/bash
# meminfo_health_check.sh
PACKAGE=$1
OUTPUT="meminfo_health_$(date +%Y%m%d_%H%M%S).txt"
echo "=== dumpsys meminfo 健康检查 ===" > $OUTPUT
echo "应用: $PACKAGE" >> $OUTPUT
echo "时间: $(date)" >> $OUTPUT
echo "" >> $OUTPUT
# 获取 meminfo 数据
MEMINFO=$(adb shell "dumpsys meminfo $PACKAGE")
echo "$MEMINFO" >> $OUTPUT
# 提取关键指标
TOTAL_PSS=$(echo "$MEMINFO" | grep "TOTAL PSS:" | awk '{print $3}')
JAVA_HEAP=$(echo "$MEMINFO" | grep "Java Heap:" | awk '{print $3}')
NATIVE_HEAP=$(echo "$MEMINFO" | grep "Native Heap:" | awk '{print $3}')
GRAPHICS=$(echo "$MEMINFO" | grep "Graphics:" | awk '{print $3}')
ACTIVITIES=$(echo "$MEMINFO" | grep "Activities:" | awk '{print $2}')
VIEWS=$(echo "$MEMINFO" | grep "Views:" | awk '{print $2}')
echo "" >> $OUTPUT
echo "=== 健康评估 ===" >> $OUTPUT
echo "总 PSS: $TOTAL_PSS KB" >> $OUTPUT
echo "Java 堆: $JAVA_HEAP KB" >> $OUTPUT
echo "Native 堆: $NATIVE_HEAP KB" >> $OUTPUT
echo "图形内存: $GRAPHICS KB" >> $OUTPUT
echo "Activity 数: $ACTIVITIES" >> $OUTPUT
echo "View 数: $VIEWS" >> $OUTPUT
# 计算比例
if [ -n "$TOTAL_PSS" ] && [ "$TOTAL_PSS" -gt 0 ]; then
GRAPHICS_RATIO=$((GRAPHICS * 100 / TOTAL_PSS))
JAVA_RATIO=$((JAVA_HEAP * 100 / TOTAL_PSS))
NATIVE_RATIO=$((NATIVE_HEAP * 100 / TOTAL_PSS))
echo "" >> $OUTPUT
echo "=== 内存分布 ===" >> $OUTPUT
echo "图形内存占比: $GRAPHICS_RATIO%" >> $OUTPUT
echo "Java 堆占比: $JAVA_RATIO%" >> $OUTPUT
echo "Native 堆占比: $NATIVE_RATIO%" >> $OUTPUT
# 健康评估
echo "" >> $OUTPUT
echo "=== 健康状况 ===" >> $OUTPUT
if [ "$TOTAL_PSS" -lt 80000 ]; then
echo "✅ 总内存: 优秀 (<80MB)" >> $OUTPUT
elif [ "$TOTAL_PSS" -lt 150000 ]; then
echo "🟡 总内存: 良好 (80-150MB)" >> $OUTPUT
elif [ "$TOTAL_PSS" -lt 250000 ]; then
echo "⚠️ 总内存: 警告 (150-250MB)" >> $OUTPUT
else
echo "🔴 总内存: 危险 (>250MB)" >> $OUTPUT
fi
if [ "$GRAPHICS_RATIO" -lt 20 ]; then
echo "✅ 图形内存占比: 优秀 (<20%)" >> $OUTPUT
elif [ "$GRAPHICS_RATIO" -lt 40 ]; then
echo "🟡 图形内存占比: 良好 (20-40%)" >> $OUTPUT
else
echo "⚠️ 图形内存占比: 过高 (>40%)" >> $OUTPUT
fi
if [ "$ACTIVITIES" -le 2 ]; then
echo "✅ Activity 数量: 正常" >> $OUTPUT
else
echo "⚠️ Activity 数量: 异常 (可能泄漏)" >> $OUTPUT
fi
fi
echo "" >> $OUTPUT
echo "详细报告: $OUTPUT"- 系统级分析: /proc/meminfo 解释指南
- 进程级概览: showmap 解释指南
- 详细映射分析: smaps 解释指南
- 解析结果理解: 分析结果指南
- 一键分析:
python3 analyze.py live --package <package> - 全景分析:
python3 analyze.py panorama -d ./dump - HPROF 分析:
python3 tools/hprof_dumper.py/python3 tools/hprof_parser.py - SMAPS 解析:
python3 tools/smaps_parser.py - Meminfo 解析:
python3 tools/meminfo_parser.py -f meminfo.txt
- Android Studio Profiler: 实时内存监控
- MAT (Memory Analyzer Tool): Java 堆分析
- LeakCanary: 自动内存泄漏检测
# 建立内存监控基准
./meminfo_monitor.sh com.example.app
# 关键节点检测
# - 应用启动后
# - 主要功能使用后
# - 长时间运行后
# - 内存敏感操作前后- 快速评估: 查看 App Summary 的内存分布
- 异常识别: 重点关注占比过高的内存类型
- 详细分析: 使用对应工具深入分析
- 趋势监控: 对比多个时间点的数据
- 图形内存: 如果占比 >40%,优先优化位图和 GPU 使用
- Java 堆: 如果持续增长,重点分析 HPROF
- Native 堆: 如果过大,检查 C/C++ 代码和第三方库
- 对象泄漏: Activity/View 数量异常需立即处理
- 建立内存使用规范和 Code Review 检查点
- 集成自动化内存检测工具
- 定期进行内存压力测试
- 建立内存使用监控和报警机制
通过深入理解 dumpsys meminfo 的每一项输出,可以准确诊断应用内存问题,制定针对性的优化策略,显著改善应用的内存性能。