使用 Memory Profiler查看Java堆和内存分配

Memory Profiler是Android Profiler中的一个组件,可帮助您识别导致应用卡顿、冻结甚至崩溃的内存泄漏和流失。它显示了应用程序内存使用的实时图形,可以捕获堆转储,强制垃圾收集以及跟踪内存分配。

为什么要分析应用的内存
Android提供了一个托管的内存环境,当它确定你的应用程序不再使用某些对象时,垃圾回收器会将未使用的内存释放回堆中。 Android如何发现未使用的内存正在不断改进,但在所有Android版本的某个时刻,系统必须暂停您的代码。大多数时候,暂停是不可思议的。但是,如果您的应用程序分配内存的速度超过系统收集内存的速度,那么在收集器释放足够的内存以满足您的分配时,您的应用程序可能会延迟。延迟可能会导致您的应用程序跳过帧,并导致可见的缓慢。

即便你的应用程序不显示缓慢,如果它泄漏内存,程序在后台时也会保留该内存。这种行为会降低系统内存性能。最终,系统被迫杀死你的应用程序进程回收内存。然后,当用户返回到您的应用程序,它必须完全重新启动。

为了帮助防止这些问题,您应该使用Memory Profiler执行以下操作:

  • 在时间轴中寻找可能导致性能问题的不良内存分配模式。
  • 在Java堆以查看哪些对象正在长期使用内存。长时间的堆转储可以帮助识别内存泄漏。
  • 在正常和极端的用户交互过程中记录内存分配,以确定代码在短时间内分配太多对象或分配泄漏对象的位置。
    (关于堆转储请参考http://www.cnblogs.com/ungshow/archive/2012/04/05/2432846.html)

Memory Profiler预览
使用 Memory Profiler查看Java堆和内存分配_第1张图片

1.用于强制执行垃圾回收 Event 的按钮。
2.用于捕获堆转储的按钮。
3.用于记录内存分配情况的按钮。 此按钮仅在连接至运行 Android 7.1 或更低版本的设备时才会显示。
4.用于放大/缩小时间线的按钮。
5.用于跳转至实时内存数据的按钮。
6.Event 时间线,其显示 Activity 状态、用户输入 Event 和屏幕旋转 Event。
7.内存使用量时间线,其包含以下内容:

  • 一个显示每个内存类别使用多少内存的堆叠图表,如左侧的 y 轴以及顶 部的彩色键所示。
  • 虚线表示分配的对象数,如右侧的 y 轴所示。
  • 用于表示每个垃圾回收 Event 的图标。

不过,如果您使用的是运行 Android 7.1 或更低版本的设备,则默认情况下,并不是所有分析数据均可见。 如果您看到一条消息,其显示“Advanced profiling is unavailable for the selected process”,则需要启用高级分析以查看下列内容:

  • Event 时间线
  • 分配的对象数
  • 垃圾回收 Event

在 Android 8.0 及更高版本上,始终为可调试应用启用高级分析。

** 如何计算内存**
Memory Profiler 顶部的内存计数图例

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

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

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

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

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

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

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

  • Allocated:您的应用分配的 Java/Kotlin 对象数。 它没有计入 C 或 C++ 中分配的对象。
    当连接至运行 Android 7.1 及更低版本的设备时,此分配仅在 Memory Profiler 连接至您运行的应用时才开始计数。 因此,您开始分析之前分配的任何对象都不会被计入。 不过,Android 8.0 附带一个设备内置分析工具,该工具可记录所有分配,因此,在 Android 8.0 及更高版本上,此数字始终表示您的应用中待处理的 Java 对象总数。

与以前的 Android Monitor 工具中的内存计数相比,新的 Memory Profiler 以不同的方式记录您的内存,因此,您的内存使用量现在看上去可能会更高些。 Memory Profiler 监控的类别更多,这会增加总的内存使用量,但如果您仅关心 Java 堆内存,则“Java”项的数字应与以前工具中的数值相似。

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

注:目前,Memory Profiler 还会显示应用中的一些误报的原生内存使用量,而这些内存实际上是分析工具使用的。 对于大约 100000 个对象,最多会使报告的内存使用量增加 10MB。 在这些工具的未来版本中,这些数字将从您的数据中过滤掉

Memory Profiler 可以帮助了解基本的系统健康和性能
,但是不能追踪相关问题。

Memory Heap/heap viewer(DDMS) 准确定位占用内存的对象;可以找出代码中已生成未被释放的对象,已生成未被使用的对象,可以从现有对象中复用,却再次生成了。
Allocation Tracker 查看内存抖动,追踪对象在代码中的具体位置

Heapviewer 的使用
Heapviewer 的使用

资料来自[https://developer.android.com/studio/profile/memory-profiler.html#overview]
文章用于自己学习记录,如有错误,请指正

你可能感兴趣的:(android)