##背景
- 内存是大问题但普遍缺乏关注 内存问题比较隐蔽,表现不明显; 内存问题相对复杂,内存问题不是孤立的,它是一个累积的过程;
##内存问题
-
内存抖动:工具内存图显现锯齿状; 导致GC频繁,进而导致程序卡顿;
-
内存泄漏:可用内存逐渐减少; 如果程序没有内存,还是要申请内存的话,程序就会企图通过GC回收得到内存, 如此可能导致频繁GC,也会产生卡顿;
-
内存溢出:OOM,导致程序异常、崩溃;
##工具
- Memory Profiler
- Memory Analyzer
- LeakCanary( Leak n.泄漏; Canary n.[动]金丝雀; 淡黄色; )
##Memory Profiler
-
是Android Studio 工具
-
实时图表展示应用内存使用量
-
识别内存泄漏、抖动(图形出现锯齿状)等 这里识别的内存泄漏,只是一个简单的判断,
-
提供捕获
堆转储、强制GC以及跟踪内存分配的能力 -
方便直观,线下平时使用
#####实战(笔者环境是 AS 3.3.1)
-
打开并运行项目, 可以看到一个这样的图标,即是
Memory Profiler -
或者在顶层栏如下操作:
选中后工具图标就会出现在下方:
-
点击工具,把
工具界面往上拉, 可以看到它左上角有一个加号, 点击之后可以选择想要跟踪的进程: -
可以看到有四块分区——
CPU、MEMORY(内存)、NETWORK(网络)、ENERGY当然我们这里只关注MEMORY(内存), 可以点击上图中的MEMORY(内存)区域, 进入更详细的图表: -
上面有个垃圾桶的图标, 点击一次即进行一次GC操作:
-
另外是GC按钮右边的这个按钮, 实现的是
堆转储的功能, 将内存当中的信息转成一个文件: -
堆转储按钮右侧,有一个Recode按钮,可以记录点击之后的分配内存的情况, 这个按钮只有测试机在Android7.1或更低版本的系统才可以显示出来, 高版本不显示;
-
右上的按钮,其实就是放大缩小图表显示的功能:
-
把鼠标放在图表上,会实时显示一条时刻线以及对应时刻的数据表, 第一行是对应的时间时刻, 往后是对应时间的内存使用情况: Total,总使用内存;
- Java:从 Java 或 Kotlin 代码分配的对象内存。
- Native:从 C 或 C++ 代码分配的对象内存。 即使应用中不使用 C++,也可能会看到此处使用的一些原生内存, 因为 Android 框架使用原生内存代表我们处理各种任务,如处理图像资源和其他图形时,即使我们编写的代码采用 Java 或 Kotlin 语言。
- Graphics:图形缓冲区队列向屏幕显示像素(包括 GL 表面、GL 纹理等等)所使用的内存。 (请注意,这是与 CPU 共享的内存,不是 GPU 专用内存。)
- Stack: 应用中的原生堆栈和 Java 堆栈使用的内存。 这通常与我们的应用运行多少线程有关。
- Code:应用用于处理代码和资源 (如 Java文件、dex 字节码、已优化或已编译的 dex 码、.so 库和字体)的内存。
- Other:应用使用的系统不确定如何分类的内存。
- Allocated:应用分配的 Java/Kotlin 对象数。 它没有计入 C 或 C++ 中分配的对象。
当连接至运行 Android 7.1 及更低版本的设备时,此分配仅在 Memory Profiler 连接至我们运行的应用时才开始计数。 因此,开始分析之前分配的任何对象都不会被计入。 不过,Android 8.0 附带一个设备内置分析工具,该工具可记录所有分配, 因此,在 Android 8.0 及更高版本上, 此数字始终表示我们的应用中待处理的 Java 对象总数。
-
操作
堆转储功能,点击堆转储按钮, 工具会自动把一定时间内的分配内存情况 以文件的方式展现出来:右上角的
Allocation代表着已经分配的对象(数目),Shallow Size:此堆中所有实例的总大小(以字节为单位)。Retained Size:为此类的所有实例而保留的内存总大小(以字节为单位) -
在左边点击一下Bitmap的这个Class, 可以看到右边会弹出一个窗口,显示Bitmap所创建的对象:
-
点击任意一个实例对象,又可以看进一步的详细信息:
- Depth:从任意 GC 根到所选实例的最短 hop 数。
- Shallow Size:此实例的大小。
- Retained Size:此实例支配的内存大小(根据 dominator 树)。
- 如此我们便可以知道内存当中有多少Bitmap, 以及Bitmap长什么样子(有的实例除了Reference这个栏,还会有Bitmap Preview一栏)
- 有时候有
Allocation CallBack的栏目, 它记录的选中对象分配的位置,也就是该对象是在哪个地方创建的:选中任意一个创建位置,可以右键之后,点击弹出项目的
Jump to Source,直接跳转到源码对应的位置:
##Memory Analyzer
- 强大的Java Heap 分析工具,查找内存泄漏及内存占用
- 生成整体报告、分析问题等;
- 线下深入使用,配合Memory Profiler
##LeakCanary
- 自动内存泄漏检测
- 官网:github.com/square/leak…
- 需线下集成,线上可能会出现错误
#####参考自 慕课网