由于项目里之前线上版本出现过一定比例的OOM,虽然比例并不大,但是还是暴露了一定的问题,所以打算对我们App分为几个步骤进行内存分析和优化,当然内存的优化是个长期的过程,不是一两个版本的事,每个版本都需要收集线上内存数据进行监控以及分析。
版本迭代过程中,内存增长过快,不仅会导致一定概率的OOM,运行时若出现内存抖动,导致频繁GC,则会对App的流畅度以及用户体验造成很大影响。
本文主要会根据实际项目中优化步骤分为以下几部分:
1. Android内存分析基础
2. 内存泄漏
3. 静态内存分析优化
4. 运行时内存分析优化
5. 监控
1.Android内存分析基础
这部分主要先介绍一些进行内存分析的基础方法以及工具,对这部分比较熟悉的同学可以先跳过哈。
一.App的内存使用情况概览
每个App进程可以分配到的最大内存是有限的,当然不同手机每个App进程可以分配到的最大内存有可能不一样,可以通过以下命令进行查看:
adb shell getprop | grep dalvik.vm.heapsize
我们可以输出我们App的内存使用情况概览:
adb shell dumpsys meminfo 包名
我们就可以看到:
Pss
: 该进程独占的内存+与其他进程共享的内存(按比例分配,比如与其他3个进程共享9K内存,则这部分为3K)
Privete Dirty
:该进程独享内存
Heap Size
:分配的内存
Heap Alloc
:已使用的内存
Heap Free
:空闲内存
二、Android Profiler
AndroidStduio3.0后Android Profiler变得比之前更强大,内存分析页变得更加直观更加方便,下面是截图:
* 进程占用总内存
* javaHeap
:这部分内存大小是有限制的,溢出则会OOM,这部分内存也是我们分析优化的重点
* NativeHeap
:native层的 so 中调用malloc或new创建的内存,对于单个进程来说大小没有限制,所以可以利用在native层分配内存来缓解javaHeap的压力(比如2.3.3之前Android Bitmap的内存分配就是在native层,之后移到javaHeap, 8.0又回到native)
* Graphics
:这部分一般游戏app中用的较多,OpenGL和SurfaceFlinger相关的内存,若没有直接调用到OpenGL,则一般不会涉及到这块内存
* Stack
:栈,了解jvm内存模型的应该都知道
* Code
: 代码,主要是dex以及so等占用的内存
* Others
:就是others啦
所以我们可以看到事实上我们可以优化的点有:JavaHeap、NativeHeap、Stack、Code所占用的内存
三、强大的MAT
MAT是做比较细致的内存分析的利器了,功能十分强大,其中的:
Hisogram
:Lists number of instances per class