掌握Memory Profiler技巧:识别内存问题

简介: Memory Profiler 是 Android Profiler 中的一个组件,可帮助您识别可能会导致应用卡顿、冻结甚至崩溃的内存泄露和内存抖动。它显示一个应用内存使用量的实时图表,让您可以捕获堆转储、强制执行垃圾回收以及跟踪内存分配。

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。

@TOC

在这里插入图片描述

一、导读

我们继续总结学习Android 基础知识,温故知新。

二、概览

Memory Profiler 是 Android Profiler 中的一个组件,可帮助您识别可能会导致应用卡顿、冻结甚至崩溃的内存泄露和内存抖动。
它显示一个应用内存使用量的实时图表,让您可以捕获堆转储、强制执行垃圾回收以及跟踪内存分配。

Memory Profiler我们主要用于识别内存泄漏、抖动 ,提供捕获堆转储、强制GC、跟踪内存分配
通过Memory Profiler 保存的堆转储文件,需要进行一次转换才能在MAT中打开。

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

hprof-conv是 android sdk 工具,目录\Sdk\platform-tools

官网说明文档

三、如何使用

如下图所示,依次点击profile - memory ,然后会跳转到 memory界面,然后就可以进行录制了。
1

如果找不到依次点击 菜单栏的 View > Tool Windows > Profiler

四、页面说明

在memory页面,有两个内存录制选项,下面分别来说明

4.1 Java 和 Kotlin 分配情况分析

当完成录制后,其界面如下图所示,我们来分别说明一下:
在这里插入图片描述

我们大致分成七个部分

4.1.1 时间轴及对应的内存

可以随时在时间轴上拖动以选择要查看哪个区域的分配,最上面是页面及用户操作记录

4.1.2 tab & visualization

4.1.3

过滤器
您可以使用已分配对象列表上方的两个菜单选择需检查的堆以及如何组织数据,如下图所示:
在这里插入图片描述

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

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

  • View app heap:选择的应用在其中分配内存的主堆。如果我们只关心我们App的话,选这项即可。

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

4.1.4

过滤器
在这里插入图片描述

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

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

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

一般采用采用Arrang by class过滤占用内存占比比较高的类进行分析,Arrang by package根据包名定位自己代码、三方代码的内存问题

4.1.5

输入过滤:在输入框中可以输入类名/包名来快速定位到具体类/包名下类的内存分配情况

4.1.6 class name

创建的对象数其分配内存情况
这部分会列举过滤之后的所有类名、分配的对象数及内存使用情况,包括

  • Class Name: 类名
  • ==Allocations==: 此类创建的实例对象数量
  • Dellocations:对象堆中释放数(低于8.0手机无此项)
  • ==Total count==:对象在堆中未被回收的数量
  • Shallow Size: 此类使用的java内存总量(单位字节)
  • Native Size: 此类总共使用的原生内存总量(只有android7.0+设备才能看到)(单位字节)
  • Retained Size: 此类实例对象仍存活而保留的内存总大小(单位字节)

4.1.7 instance

类实例对象列表及其实例对象的详细信息
在6中点击某一个类,会在下半部分显示此类的所有实例对象的信息,如图
在这里插入图片描述

最右边的 Call Stack 标签页,显示该实例被分配到何处以及在哪个线程中。

4.2 堆转储文件分析

当完成录制后,其界面如下图所示,我们来分别说明一下:
在这里插入图片描述
我们大致分成4个部分

4.2.1 过滤器

在这里插入图片描述

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

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

  • View app heap:选择的应用在其中分配内存的主堆。如果我们只关心我们App的话,选这项即可。

  • View all heaps: 检查分配内存的所有堆。

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

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

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

  • Show all class: 默认,显示所有的类

  • Show activity/fragment Leak: 显示发生内存泄漏的activity/fragment
  • Show project class: 进显示项目相关的类

一般采用采用Arrang by class过滤占用内存占比比较高的类进行分析,Arrang by package根据包名定位自己代码、三方代码的内存问题

输入过滤:在输入框中可以输入类名/包名来快速定位到具体类/包名下类的内存分配情况

4.2.2 统计信息

classes: 类类型总数,不是实例对象哦
Leaks:发生内存泄漏的数量
count: 总关创建的使用的实例对象数
Native Size: 原生c/c++使用的内存总量
Shallow Size: java使用的内存总量
Retained Size: 还在使用保留的内存总量

4.2.3 class name

创建的对象数其分配内存情况
这部分会列举过滤之后的所有类名、分配的对象数及内存使用情况,包括

  • Class Name: 类名
  • Allocations: 此类创建的实例对象数量
  • Native Size: 此类总共使用的原生内存总量(只有android7.0+设备才能看到)(单位字节)
  • Shallow Size: 此类使用的java内存总量(单位字节)
  • Retained Size: 此类实例对象仍存活而保留的内存总大小(单位字节)

4.2.4 instance

类实例对象列表及其实例对象的详细信息
在这里插入图片描述

点击某个实例会在右侧显示此实例内存分配的详细信息,包括:Fields、References:

  • Fields
    实例对象每个字段信息,包括如下信息:

  • Instance 此字段的名称及其类型,如果是基本数据类型和String会同时显示此字段的当前值

  • Depth: 此字段可达的最短跳数,表示的是任意一个GC Root到此字段的最短链路边数
  • Native Size: 原生内存中此字段的内存大小(只有Android7.0+上的设备才会看到此列)
  • Shallow Size: Java 内存中此字段的内存大小
  • Retained Size: 此字段目前还保留的内存大小

  • References:
    实例对象的引用链信息,References中包括如下信息:

  • Reference: 实例对象的引用链,可以依次点击展开显示此实例被哪些实例对象所引用,通过引用链可以最终追踪到GC Root

  • Depth: 此实例对象可达的最短跳数,表示的是任意一个GC Root到此实例对象的最短链路边数
  • Native Size: 原生内存中此实例对象的内存大小(只有Android7.0+上的设备才会看到此列)
  • Shallow Size: Java 内存中此实例对象的内存大小
  • Retained Size: 此实例对象目前还保留的内存大小

我们可以在Fields和References中分析,
可以右键选择Go to Instance显示其实例内存数据;
或者选择Jump to source进入此实例对象所在的源码。

五、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

相关文章
|
3月前
|
Python
什么是Python中的内存池(Memory Pool)?
什么是Python中的内存池(Memory Pool)?
34 0
|
3月前
|
数据库 数据库管理 Python
解释Python中的内存视图(Memory View)。
解释Python中的内存视图(Memory View)。
|
15天前
|
JavaScript 前端开发
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 内存溢出问题
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 内存溢出问题
17 1
|
4月前
|
存储 缓存 Java
Java内存模型(Java Memory Model,JMM)
Java内存模型(Java Memory Model,JMM)
24 0
|
5月前
|
存储 Java C#
C# | 使用Memory<T>高效地读写内存数据
Memory<T>是什么? 它是一种可变大小、可读写的内存块,可以安全地暴露给用户代码进行操作。 为什么要使用Memory<T>? 使用它有许多好处。最主要的是善用它可以提高代码的性能。因为Memory<T>是可变的,所以我们可以直接在内存中操作数据,而不需要进行额外的拷贝操作。 使用Memory<T>还可以减少垃圾回收的压力,因为我们不需要创建新的对象来存储数据。 Memory<T>还可以与Span<T>和ReadOnlySpan<T>类型一起使用,这些类型可以方便地对数据进行访问和操作。
36 0
|
7月前
|
SQL 人工智能 移动开发
Memory Analyzer(MAT)分析内存
MAT是Memory Analyzer tool的缩写,是一款非常强大的内存分析工具,只需要打开采集的hprof文件即可开始对内存开始分析对比,一款“傻瓜式“的堆转储文件分析工具,谁都能学会。
|
8月前
|
SQL 数据库
使用 SAP ABAP Memory Inspector 对应用程序消耗内存进行检测时常犯的错误试读版
使用 SAP ABAP Memory Inspector 对应用程序消耗内存进行检测时常犯的错误试读版
68 0
|
8月前
ABAP Memory Inspector 里对动态内存对象的内存消耗度量方式
ABAP Memory Inspector 里对动态内存对象的内存消耗度量方式
46 0
|
8月前
|
Web App开发 缓存 JavaScript
使用 Chrome 开发者工具的 Memory 标签页分析内存泄漏问题
使用 Chrome 开发者工具的 Memory 标签页分析内存泄漏问题
178 0
|
8月前
|
缓存 Oracle 关系型数据库
Linux 内存管理新特性 - Memory folios 解读
if (compound_head(page)) // do A; else // do B; folio 并不完美,或许因为大家期望太高,导致少数人对 folio 的最终实现表示失望。但多数人认为 folio 是在正确方向上的重要一步。毕竟后续还有更多工作要实现。
225 0