Android应用开发那些事

Android内存分析工具 — Memory Profiler

2019-07-22  本文已影响0人  Geekholt

目录

前言

Android 存在内存回收机制,当它确定应用不再使用某些对象时,垃圾回收器会将未使用的内存释放回堆中。 虽然 Android 查找未使用内存的方式在不断改进,但对于所有 Android 版本,系统都必须在某个时间点短暂地暂停你写的代码。 大多数情况下,这些暂停难以察觉。 但是,如果你的应用分配内存的速度比系统回收内存的速度快,那么当释放足够的内存以满足应用的分配需要时,应用就可能出现延迟。 这样可能会导致应用跳帧,并使系统明显变慢

如果存在内存泄漏,则即使应用在后台运行也会保留该内存。 此行为会强制执行不必要的垃圾回收事件,因而拖慢系统的内存性能。 最后,系统被迫终止你的应用进程以回收内存。 然后,当用户返回你的应用时,就必须完全重启

为帮助防止这些问题,我们可以使用Memory Profiler

Memory Profiler 概览

图 1. Memory Profiler

如图 1 所示,Memory Profiler 的默认视图包括以下各项:

  1. 强制执行垃圾回收

  2. 堆转储,把内存信息通过文件的方式保存下来,可以进行分析

  3. 记录内存分配情况, 此按钮仅在连接至运行 Android 7.1 或更低版本的设备时才会显示

  4. 放大/缩小时间线

  5. 跳转至实时内存数据

  6. Event 时间线,显示 Activity 状态、用户输入 Event 和屏幕旋转 Event

  7. 内存使用量时间线,其包含以下内容:

    • 一个显示每个内存类别使用多少内存的堆叠图表,如左侧的 y 轴以及顶部的彩色键所示

    • 虚线表示分配的对象数,如右侧的 y 轴所示

    • 用于表示每个垃圾回收 Event 的图标

如何计算内存占用

图 2. Memory Profiler 顶部的内存计数图例

内存计数中的类别如下所示:

Java 数字可能与你在 Android Monitor 中看到的数字并非完全相同,这是因为应用的 Java 堆是从 Zygote 启动的,而新数字则计入了为它分配的所有物理内存页面。 因此,它可以准确反映你的应用实际使用了多少物理内存

查看内存分配

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

  1. 浏览列表以查找堆计数异常大且可能存在泄漏的对象。 点击 Class Name 列标题以按字母顺序排序。 然后点击一个类名称。 此时在右侧将出现 Instance View 窗格,显示该类的每个实例,如图 3 中所示
  2. Instance View 窗格中,点击一个实例。 此时下方将出现 Call Stack 标签,显示该实例被分配到何处以及哪个线程中
  3. Call Stack 标签中,点击任意行以在编辑器中跳转到该代码
图 3. 有关每个已分配对象的详情显示在右侧的 **Instance View** 中

默认情况下,左侧的分配列表按类名称排列。 在列表顶部,你可以使用右侧的下拉列表在以下排列方式之间进行切换:

捕获堆转储

堆转储显示在您捕获堆转储时您的应用中哪些对象正在使用内存

要捕获堆转储,在 Memory Profiler 工具栏中点击 Dump Java heap

。 在转储堆期间,Java 内存量可能会暂时增加。因为堆转储与您的应用发生在同一进程中,并需要一些内存来收集数据

注:如果您需要更精确地了解转储的创建时间,可以通过调用 Debug.dumpHprofData() 在应用代码的关键点创建堆转储

要检查堆信息,请按以下步骤操作:

  1. 浏览列表以查找堆计数异常大且可能存在泄漏的对象。 为帮助查找已知类,点击 Class Name 列标题以按字母顺序排序。 然后点击一个类名称。 此时在右侧将出现 Instance View 窗格,显示该类的每个实例,如图 5 中所示
  2. Instance View窗格中,点击一个实例。此时下方将出现References,显示该对象的每个引用
  3. References 标签中,如果您发现某个引用可能在泄漏内存,则右键点击它并选择 Go to Instance

在堆转储中,请注意由下列任意情况引起的内存泄漏:

图 4. 捕获堆转储需要的持续时间标示在时间线中

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

在类列表顶部,你可以使用左侧下拉列表在以下堆转储之间进行切换:

Instance View 中,每个实例都包含以下信息:

分析内存的技巧

使用 Memory Profiler 时,你可以应用代码施加压力并尝试强制内存泄漏。 在应用中引发内存泄漏的一种方式是,先让其运行一段时间,然后再检查堆。 泄漏在堆中可能逐渐汇聚到分配顶部。 不过,泄漏越小,你越需要运行更长时间的应用才能看到泄漏

您还可以通过以下方式之一触发内存泄漏:

上一篇 下一篇

猜你喜欢

热点阅读