了解和排查 Android 内存问题

内存是 Android 设备上的一项关键且有限的资源。作为 Android 平台开发者或原始设备制造商 (OEM),了解内存在各个层级(从 Java 运行时到 Linux 内核)的工作方式对于构建高性能且稳定的系统至关重要。

本指南全面介绍了 Android 内存架构、可用于分析的工具,以及帮助您识别和解决内存相关问题的实践练习。

目标

完成本指南后,您将能够:

  • 解释 Android 内存的基本概念,包括 Zygote 进程模型和内存映射文件。
  • 区分常驻内存大小 (RSS)、按比例分摊的内存大小 (PSS) 和独占内存大小 (USS)。
  • 使用标准命令行工具(如 dumpsys meminfoshowmap)快速评估内存用量。
  • 使用 AHAT 捕获和分析 Java 堆转储,以查找内存泄漏和过多的内存分配。
  • 使用 Perfetto 和 heapprofd 分析整个系统中的 Java 内存和原生内存。
  • 了解系统级内存压力指标(如压力停滞信息 (PSI)),并监控低内存杀手 (LMK) 活动。
  • 观察内核级回收活动,包括 ZRAM 交换和页面缓存逐出。

指南结构

本指南分为以下几个部分,建议按顺序阅读:

  1. 基本概念: Android 内存的核心技术原理。
  2. 快速评估工具:使用 meminfoshowmapprocstats 进行快速分类。
  3. 分析 Java 内存:使用 AHAT 深入了解 Java 堆。
  4. 位图和内存:了解图片如何影响 RAM 并使用工具分析图片。
  5. 分析原生内存:使用 Perfetto 和 heapprofd 分析 C/C++ 内存。
  6. WebView 和内存:了解 WebView 的多进程 架构和内存占用。
  7. 应用代码即内存:了解类加载和 dex 膨胀如何影响 RAM。
  8. 线程和内存:分析原生线程 堆栈的开销。
  9. 内存局部性和性能:了解数据 访问模式如何影响 CPU 性能。
  10. 服务绑定和进程状态: 了解跨进程依赖项如何影响 OOM 分数。
  11. 系统级问题排查:监控 PSI, LMK、ZRAM 交换和页面缓存逐出。
  12. 内存回收:逐出和交换:了解 memcg、 charge 和使用 memory.reclaim 进行主动回收。
  13. kswapd 和 lmkd 交互: 了解 kswapd 和 lmkd 如何在压力下协同工作。

前提条件和环境

本指南介绍了参考工作流、基准数据和案例研究,展示了如何诊断和解决 Android 内存问题。

  • 分析工具:本指南中的技术主要使用标准 Android 性能工具,包括 Perfettodumpsys meminfoshowmapAHAT
  • 根权限:某些系统级诊断工作流(例如 检查内核内存压力或硬件 PMU 计数器)需要在 userdebug 设备或模拟器 build 上提升根权限 (adb root)。

点击此处开始:基本概念