Android专项测试之(内存)

本文详细介绍了Android应用的内存分析,包括内存profile、内存使用情况、内存性能分析器的使用,以及如何捕获和分析堆转储以检测内存泄漏。通过监控Dalvikheapsize、使用monitor工具、dumpdalvikheap和分析HPROF文件,可以识别可能导致卡顿和OOM的问题。同时,文章提到了针对不同Android版本的内存分析差异,并提供了使用Android Studio的内存性能分析器进行性能剖析和泄漏检测的方法,以及在不同场景下触发内存泄漏的策略。

Android专项测试之(内存)

内存profile

❖ gc会导致dalvik暂停引发卡顿
❖ 超过dalvik heap size会引发OOM
❖ 常见测试场景:
	❖ dump
	❖ 进⼊activity再退出
	❖ dump and diff
❖ dump dalvik heap:am dumpheap、monitor
❖ convent to jvm heap:hprof-conv
❖ 分析并对⽐:visualVM MAT

monitor

Android的工具monitor导出内存数据,用下面“其他 HPROF 分析器内存泄漏”步骤进行分析即可
在这里插入图片描述

内存使用情况

官方文档

内存性能分析器概览

当您首次打开内存性能分析器时,您将看到一条表示应用内存使用量的详细时间轴,并可使用各种工具强制执行垃圾回收、捕获堆转储以及记录内存分配。
图 1. 内存性能分析器
如图 1 所示,内存性能分析器的默认视图包括以下各项:

  1. 用于强制执行垃圾回收事件的按钮。
  2. 用于捕获堆转储的按钮。

注意:只有在连接到搭载 Android 7.1(API 级别 25)或更低版本的设备时,系统才会在堆转储按钮右侧显示用于记录内存分配情况的按钮。

  1. 用于指定性能分析器多久捕获一次内存分配的下拉菜单。选择适当的选项可帮助您在进行性能剖析时提高应用性能。
  2. 用于缩放时间轴的按钮。
  3. 用于跳转到实时内存数据的按钮。
  4. 事件时间轴,显示活动状态、用户输入事件和屏幕旋转事件。
  5. 内存使用量时间轴,它会显示以下内容:
  • 一个堆叠图表,显示每个内存类别当前使用多少内存,如左侧的 y 轴以及顶部的彩色键所示。
  • 一条虚线,表示分配的对象数,如右侧的 y 轴所示。
  • 每个垃圾回收事件的图标。

但是,如果您使用的是搭载 Android 7.1 或更低版本的设备,并非所有分析数据在默认情况下都可见。如果您看到一条消息,显示“Advanced profiling is unavailable for the selected process”,您需要启用高级性能剖析才能看到以下内容:

  • 事件时间轴
  • 分配的对象数
  • 垃圾回收事件

在 Android 8.0 及更高版本上,系统会一律为可调试的应用启用高级性能剖析。

内存计算方式

您在内存性能分析器顶部看到的数字(图 2)基于您的应用提交的所有专用内存页面(此数据由 Android 系统根据其记录提供)。此计数不包含与系统或其他应用共享的页面。
图 2. 内存性能分析器顶部的内存计数图例
内存计数中的类别如下:

  • Java:从 Java 或 Kotlin 代码分配的对象的内存。

  • Native:从 C 或 C++ 代码分配的对象的内存。

  • 即使您的应用中不使用 C++,您也可能会看到此处使用了一些原生内存,因为即使您编写的代码采用 Java 或 Kotlin 语言,Android 框架仍使用原生内存代表您处理各种任务,如处理图像资源和其他图形。

  • Graphics:图形缓冲区队列为向屏幕显示像素(包括 GL 表面、GL 纹理等等)所使用的内存。(请注意,这是与 CPU 共享的内存,不是 GPU 专用内存。)

  • Stack:您的应用中的原生堆栈和 Java 堆栈使用的内存。这通常与您的应用运行多少线程有关。

  • Code:您的应用用于处理代码和资源(如 dex 字节码、经过优化或编译的 dex 代码、.so 库和字体)的内存。

  • Others:您的应用使用的系统不确定如何分类的内存。

  • Allocated:您的应用分配的 Java/Kotlin 对象数。此数字没有计入 C 或 C++ 中分配的对象。
    如果连接到搭载 Android 7.1 及更低版本的设备,只有在内存性能分析器连接到您运行的应用时,才开始此分配计数。因此,您开始分析之前分配的任何对象都不会被计入。但是,Android 8.0 及更高版本附带一个设备内置性能剖析工具,该工具可跟踪所有分配,因此,在 Android 8.0 及更高版本上,此数字始终表示您的应用中待处理的 Java 对象总数。

与以前的 Android Monitor 工具中的内存计数相比,新的内存性能分析器以不同的方式记录您的内存,因此,您的内存使用量现在看上去可能会更高些。内存性能分析器会监控一些额外的类别,这就增加了总的内存使用量,但如果您仅关心 Java 堆内存,“Java”项的数字应与以前工具中的数值相似。 然而,Java 数字可能与您在 Android Monitor 中看到的数字并非完全相同,这是因为新数字计入了自应用的 Java 堆从 Zygote 派生以来为其分配的所有物理内存页面。因此,它可以准确反映您的应用实际使用了多少物理内存。

注意:使用搭载 Android 8.0(API 级别 26)及更高版本的设备时,Memory Profiler 还会显示应用中的一些误报的原生内存使用量,而这些内存实际上是分析工具使用的。对于大约 100000 个对象,最多会使报告的内存使用量增加 10MB。在 IDE 的未来版本中,这些数字将从您的数据中过滤掉。

查看内存分配情况

内存分配情况图表为您显示内存中每个 Java 对象和 JNI 引用的分配方式。具体而言,内存性能分析器可为您显示有关对象分配情况的以下信息:

  • 分配了哪些类型的对象以及它们使用多少空间。
  • 每个分配的堆栈轨迹,包括在哪个线程中。
  • 对象在何时被取消分配(仅当使用搭载 Android 8.0 或更高版本的设备时)。

如果您的设备搭载的是 Android 8.0 或更高版本,您可以随时查看对象分配,具体操作步骤如下:在时间轴上拖动以选择要查看哪个区域的分配(如视频 1 中所示)。不需要开始记录会话,因为 Android 8.0 及更高版本附带设备内置分析工具,可持续跟踪您的应用分配。

https://storage.googleapis.com/androiddevelopers/videos/studio/memory-profiler-allocations-jvmti.mp4
视频 1. 对于 Android 8.0 及更高版本,选择一个现有时间轴区域以查看对象分配

如果您的设备搭载的是 Android 7.1 或更低版本,请点击内存性能分析器工具栏中的 Record memory allocations 图标 。记录时,内存性能分析器会跟踪您的应用中发生的所有分配。完成后,请点击 Stop recording 图标 (同一按钮,请观看视频 2)以查看分配。

https://storage.googleapis.com/androiddevelopers/videos/studio/memory-profiler-allocations-record.mp4
视频 2. 对于 Android 7.1 及更低版本,您必须明确记录内存分配

选择时间轴的某个区域后(或者使用搭载 Android 7.1 或更低版本的设备完成记录会话后),已分配对象的列表将显示在时间轴下方,按类名称进行分组,并按其堆计数排序。

注意:在 Android 7.1 及更低版本上,您最多可以记录 65535 个分配。 如果您的记录会话超出此限制,记录中仅保存最新的 65535 个分配。(在 Android 8.0 及更高版本上,则没有实际的限制。)

如需检查分配记录,请按以下步骤操作:

  1. 浏览列表以查找堆计数异常大且可能存在泄漏的对象。为帮助查找已知类,点击 Class Name 列标题以按字母顺序排序。然后,点击一个类名称。此时右侧将出现 Instance View 窗格,显示该类的每个实例,如图 3 所示。
  • 此外,您也可以快速找到对象,方法是点击 Filter 图标 ,或按 Ctrl+F 键(在 Mac 上,按 Command+F 键),然后在搜索字段中输入类或软件包名称。如果从下拉菜单中选择 Arrange by callstack,还可以按方法名称搜索。如需使用正则表达式,请勾选 Regex 旁边的复选框。如果您的搜索查询区分大小写,请勾选 Ma
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值