位图内存用量

位图通常是应用中占用内存最多的对象。解码和缩放操作通常位于帧渲染的关键路径上。 通过减少卡顿、ANR 和与 OOM 相关的进程终止,优化位图内存用量可以显著提高界面响应速度、电池续航时间和整体稳定性。

识别高位图内存用量

Android Vitals 通过汇总 Android 设备中的数据,提供有关应用位图内存占用空间的指标。这些指标包括基于时间段(例如 28 天)的每个软件包和进程的百分位值。这些数据有助于识别不同设备类型和版本中内存效率的趋势和潜在回归。

Android Vitals 会分享您的应用位图内存用量,并按以下 进程状态进行细分:

  • 前台:应用的进程可见。与其他进程状态相比,前台的 P99 值预计会显著更高,但如果 P99/P50 比率显著(例如高于 3.5 倍),开发者应进行调查,因为这通常表明存在位图内存泄漏。您可以通过查找典型用量 (P50) 和离群值用量 (P99) 之间的差异来识别此问题;虽然一般资源膨胀会使所有百分位值的内存均匀膨胀,但内存泄漏会随着时间的推移而加剧,严重扭曲尾端数据 (P99)。确保在前台位图分配在应用转换为其他状态后不会不必要地保留。
  • 用户感知到的服务:应用的进程以 可感知状态运行。这包括前台服务、加急 作业和用户发起的数据传输作业。应用在转换为这些状态时不得保留大量前台位图分配。由于这些服务是为长时间运行的任务而设计的,因此保留大量资源会降低整体用户体验,并迫使低内存终止守护程序 (LMKD) 通过终止优先级较低的进程来回收内存。
  • 后台:应用正在运行后台服务,或最近已转到 后台,但尚未缓存。由于此进程状态不如前台或可感知进程重要,因此应用应在此处显式释放大型位图资源,以减少内存压力。
  • 已缓存:应用处于缓存状态。此状态对系统内存压力(例如 LMK)高度敏感。应用必须在此状态下主动减少位图内存用量,以避免被操作系统逐出。

导致位图内存用量较高的因素

计算中可能还包括从未使用过的虚拟内存。如果您发现位图内存用量出乎意料地高,请验证您是否分配了未使用的内存。

资源

在 Android Studio 中分析位图

Android Studio 位图性能分析

使用内存分析器实时检查内存分配、捕获堆转储和分析对象以查找内存泄漏;此外,使用堆分析器检测内存泄漏、识别重复的位图分配并直观呈现对象保留情况。

使用 LeakCanary 自动检测泄漏

集成 LeakCanary 库以自动检测应用中的内存泄漏。LeakCanary 提供自动堆分析,可识别本应进行垃圾回收但仍保留在内存中的对象,例如被销毁的 Activity 或 Fragment 保留的位图。

位图性能文档

这些资源全面介绍了在不同 Android 组件中高效处理位图的最佳实践。

优化位图内存用量的开发者核对清单

如需优化位图内存效率,请遵循以下三个核心原则:减少、重用和回收。

  • 减少:在加载或显示 位图时,尽量减少初始内存占用空间。
  • 重用:实现缓存机制,以避免冗余位图 分配。
  • 回收:主动释放资源,以便为 活跃进程重新分配内存。

以下开发者核对清单可帮助您优化位图内存用量。

核心原则 领域 说明
减少 消除重复的位图 使用内存分析器分析堆转储,以检测冗余位图分配。请参阅管理位图内存指南。
利用图片加载库 使用 Glide 和 Coil 等库来自动执行线程处理、缓存和高效解码。
实现降采样 解码图片以匹配目标界面容器尺寸,而不是加载全分辨率资源。
将 RGB_565 用于不透明图片 通过将不透明图片的配置ARGB_8888 切换为 16 位配置,将内存占用空间减少 50%。
优先使用 VectorDrawable 矢量用于图标和基本图形,以确保清晰缩放,同时最大限度地减少内存开销。
优化服务器端图片传送 配置后端 API,以提供根据设备密度和 ImageView 尺寸量身定制的图片。
消除透明边距 通过使用 InsetDrawable 或布局内边距而不是内置边距,避免为“不可见”像素分配内存。请参阅打造内存高效的 Android 应用
重用 配置最佳缓存大小 根据设备 RAM 和屏幕分辨率调整内存和磁盘缓存限制。请参阅缓存位图
回收 在后台清除资源 实现 TRIM_MEMORY_BACKGROUND 以清除缓存,并在系统内存压力期间提高进程存活率。
在界面隐藏时释放资源 当应用对用户不可见时,使用 TRIM_MEMORY_UI_HIDDEN 释放位图缓存。
监控内存泄漏 使用 LeakCanary 和内存分析器查找在其 LifecycleOwner 销毁后保留的位图。请参阅管理应用内存