1 Memory Monitor
- Memory Monitor 是一款使用非常简单的图形化工具,可以很好地监控系统或应用的内存使用情况,主要有以下几个功能:
- 显示可用和已用内存,并且以时间为维度实时反应内存分配和回收情况。
- 快速判断应用程序的运行缓慢是否是由于过度的内存回收导致。
- 快速判断应用是否是由于内存不足导致程序崩溃。
通过观察以时间为维度实时反应内存分配和回收情况,可以快速发现内存抖动、大内存分配,甚至由于 CG 导致卡顿。
1.1 Memory Monitor 的使用介绍
- 直接使用AndroidStudio查看即可,具体打开方式不做阐述。打开以后就可以查看内存的使用情况了,如下图
- 可以单击MEMORY放大查看内存使用情况
不同的颜色代表了不同内容使用内存的情况,顶部分别有:
- Initiate GC :垃圾回收
- Dump Java heap:保存内存快照
- Allocation Tracking:使用Allocation Tracker工具,可以选择级别
- 可以随意点击图中某一时刻的内存情况,可以根据class 、package或者 callstack来筛选想要看的内容
1.2 典型场景
使用Memory Monitor 可以观察到多个不同的场景。
- 内存分配与释放
在第一段触发了系统 GC,迅速释放了一大块内存,在第二段,进入新的界面,同时申请了新的内存。通过 Memory Monitor 可以清楚地发现这种大内存分配的场景,定位观察,以判断是否为合理分配内存,是 Bitmap 还是其他数据,然后对数据进行优化,减小内存开销。
- 大内存申请与内存抖动
内存抖动,一般是指在很短的时间内发生了多次的内存分配和释放,并且通常在发生严重内存抖动时,也能感觉到应用卡顿,可以看出来是由于执行了 GC 操作造成的。频繁的GC 会导致界面卡顿,在 Memory Monitor 上,内存抖动也很容易发现。如图 3-10 所示,内存的分配过程有明显的锯齿状,带有毛剌,在这种情况下要仔细分析内容的分配情况,可以使用另外两个分析工具来查看分配了什么对象、以前分配内存的大小和分析对象的堆栈,从而结合代码进行优化。
2 Heap Viewer
- Heap Viewer 的主要功能是查看不同数据类型在内存中的使用情况,可以看到当前进程中的 Heap Size 的情况,分别有哪些类型的数据,以及各种类型数据占比情况。通过分析这些数据来找到大的内存对象,再进一步分析这些大对象,进而通过优化减少内存开销,也可以通过数据的变化发现内存泄漏。
点击 Update Heap 按钮开始,在右侧的 Heap Viewer 开始更新数据,右边面板中的数值会在每次GC时改变。
Heap Viewer 不仅可以用来检测是否有内存泄漏,还可以检测到内存抖动,因为内存抖动时,会频繁发生 GC,这时只需要开启 Heap Viewer,观察内存数据的变化,如果发生内存抖动,就可以观察到数据在这段时间内频繁更新。
- Heap Viewer面板
Heap Viewer 面板共有三个区域
- 最上面的数据区是总览区,查看整体内存情况,包括已使用和未使用的情况。
- 中间部分是详情,可以查看各种数据类型的内存开销
- 下面是具体类型内存分配图,可以查看选中类型的内存分析情况。
- 总览视图
通过总览视图可以看到所有的内存情况,单击总览视图上最右边的 Cause GC 按钮可以手动触发 GC,表中数值的对应关系如下:
- Heap Size:堆栈分配给 App 的内存大小。
- Allocated:已分配使用的内存大小。
- Free:空闲的内存大小。
- %Used:Allocated/Heap Size,使用率。
- #Objects:对象数量。
- 详情视图
详情视图页展示所有数据类型的内存情况,其中第一列为所有数据类型,类型如下:
- free:空闲的对象。
- data object:数据对象,Java 类类型对象,是最主要的观察对象。
- class object:Java 类类型的引用对象。
- 1-byte array(byte[],boolean[]):一字节的数组对象。
- 2-byte array(short[],char[]):两字节的数组对象。
- 4-byte array(long[],double[]):4 字节的数组对象。
- 8-byte array(long[],double[]):8 字节的数组对象。
- non-Java object:非 Java 对象。
在每个类型的数据值对应如下:
- Count:数量。
- Total Size:总共占用的内存大小。
- Smallest:将对象占用内存从小到大排列,排在第一个的对象占用内存大小。
- Largest:将对象占用内存的大小从小到大排列,排在最后一个的对象占用的内存大小。
- Median:将对象占用内存的大小从小到大排列,排在中间的对象占用的内存大小。
- Average:平均值。
选择一个具体数据类型后,会显示对应的内存对象柱状图,柱状图横坐标是对象的内存大小,这些值随着不同对象而不同,纵坐标是在某个内存大小上的对象的数量。