Android内存编辑器推荐,Android Studio编辑器教程

3.2 检查分析分配记录

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

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

浏览列表以查找堆计数异常大且可能存在泄露的对象。为帮助查找已知类,点击 Class Name 列标题以按字母顺序排序。然后,点击一个类名称。此时右侧将出现 Instance View 窗格,显示该类的每个实例;

在 Instance View 窗格中,点击一个实例。此时下方将出现 Call Stack 标签页,显示该实例被分配到何处以及在哪个线程中;

在 Call Stack 标签页中,右键点击任意行并选择 Jump to Source,以在编辑器中打开该代码。

6ec2d00b49e22ea973ff35a1fbb41ff7.png

我们可以使用已分配对象列表上方的两个菜单来选择要检查的堆以及如何组织数据。从左侧的菜单中,选择要检查的堆:

default heap:当系统未指定堆时;

image heap:系统启动映像,包含启动期间预加载的类。此处的分配保证绝不会移动或消失;

zygote heap:写时复制堆,其中的应用进程是从 Android 系统中派生的;

app heap:我们的应用在其中分配内存的主堆;

JNI heap:显示 Java 原生接口 (JNI) 引用被分配和释放到什么位置的堆。

从右侧的菜单中,选择如何安排分配:

Arrange by class:根据类名称对所有分配进行分组。这是默认选项;

Arrange by package:根据软件包名称对所有分配进行分组;

Arrange by callstack:将所有分配分组到其对应的调用堆栈;

3.2 查看全局 JNI 引用

JNI 引用由原生代码进行管理,因此原生代码使用的 Java 对象可能会保持活动状态太长时间。如果丢弃了 JNI 引用而未先明确将其删除,Java 堆上的某些对象可能会变得无法访问。此外,还可能会达到全局 JNI 引用限制。

要排查此类问题,请使用 Memory Profiler 中的 JNI heap 视图来浏览所有全局 JNI 引用,并按 Java 类型和原生调用堆栈对其进行过滤。借助此信息,我们可以了解创建和删除全局 JNI 引用的时间和位置。

在我们的应用运行时,选择我们要检查的一部分时间轴,然后从类列表上方的下拉菜单中选择 JNI heap。 我们随后可以像往常一样检查堆中的对象,还可以双击 Allocation Call Stack 标签页中的对象,以查看在代码中将 JNI 引用分配和释放到了什么位置,如下图所示。

5f2d3946dd5563bb60f4e5364a21bac6.png

Tips:要检查应用的 JNI 代码的内存分配,必须将应用部署到搭载 Android 8.0 或更高版本的设备上。

4. 堆转储

堆转储显示在我们捕获堆转储时我们的应用中哪些对象正在使用内存。特别是在长时间的用户会话后,堆转储会显示我们认为不应再位于内存中却仍在内存中的对象,从而帮助识别内存泄露。

捕获堆转储后,我们可以查看以下信息:

我们的应用分配了哪些类型的对象,以及每种对象有多少;

每个对象当前使用多少内存;

在代码中的什么位置保持着对每个对象的引用;

对象所分配到的调用堆栈。

4.1 如何捕获堆转储

要捕获堆转储,请点击 Memory Profiler 工具栏中的 Dump Java heap 图标。 在转储堆期间,Java 内存量可能会暂时增加。 这很正常,因为堆转储与我们的应用发生在同一进程中,并需要一些内存来收集数据。

堆转储出现在内存时间轴下方,显示堆中的所有类类型,如下图所示。

d88e1b3df60f7e1a203fc0581c0b5a53.png

在类列表中,我们可以查看以下信息:

Allocations:堆中的分配数;

Native Size:此对象类型使用的原生内存总量(以字节为单位)。只有在使用 Android 7.0 及更高版本时,才会看到此列;

Shallow Size:此对象类型使用的 Java 内存总量(以字节为单位);

Retained Size:为此类的所有实例而保留的内存总大小(以字节为单位);

点击一个类名称可在右侧打开 Instance View 窗口。列出的每个实例都包含以下信息:

Depth:从任意 GC 根到选定实例的最短跳数;

Native Size:原生内存中此实例的大小。 只有在使用 Android 7.0 及更高版本时,才会看到此列;

Shallow Size:Java 内存中此实例的大小;

Retained Size:此实例所支配内存的大小;

ff37ec024b62abbd97e6ddf5fe3789ef.png

要检查应用的堆,请按以下步骤操作:

浏览列表以查找堆计数异常大且可能存在泄露的对象。为帮助查找已知类,点击 Class Name 列标题以按字母顺序排序。然后,点击一个类名称。此时右侧将出现 Instance View 窗格,显示该类的每个实例;

在 Instance View 窗格中,点击一个实例。此时下方将出现 References 标签页,显示对该对象的每个引用;

在 References 标签页中,如果我们发现某个引用可能在泄露内存,请右键点击它并选择 Go to Instance。这样会从堆转储中选择相应的实例,从而向我们显示它自己的实例数据。

4.2 HPROF 文件

捕获堆转储后,只有在 Memory Profiler 正在运行时,才能在该分析器中查看数据。当我们退出分析会话时,会丢失堆转储。因此,如果我们要保存堆转储以供日后查看,请将其导出到 HPROF 文件。

Sessions 窗格中每个 Heap Dump 条目的右侧都有一个 Export Heap Dump 按钮。在随即显示的 Export As 对话框中,使用 .hprof 文件扩展名保存文件。

要使用其他 HPROF 分析器(如 jhat),我们需要将 HPROF 文件从 Android 格式转换为 Java SE HPROF 格式。 我们可以使用 android_sdk/platform-tools/ 目录中提供的 hprof-conv 工具执行此操作。运行包含两个参数(即原始 HPROF 文件和转换后 HPROF 文件的写入位置)的 hprof-conv 命令。例如:

hprof-conv heap-original.hprof heap-converted.hprof

5. 小结

本节课程我们主要学习了如何分析内存活动。本节课程的重点如下:

掌握如何查看内存分配和堆;

掌握如何检查分析内存数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值