前言
在前两篇对Android如何管理内存有一定的了解下,所以本篇文章就是如何进行内存优化。因为Android给每个应用分配的内存是有限的,所以要保证应用占用的内存最小,这样提高让进程长时间存活的概率,并且不易发生OOM。
1. 内存问题
- 内存泄露
- 内存抖动
- 内存消耗过大
内存泄漏概念(Memory Leaks):
就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。内存泄露引起的问题:
- 应用卡顿,响应速度慢(内存占用高时JVM虚拟机会频繁触发GC,引起掉帧);
- 应用在后台时被系统回收;
- 引起OOM;
内存抖动概念(Memory Churn):
即大量的对象被创建又在短时间内马上被释放。
memory churn can cause a large number of garbage collection events to occur. 内存抖动会触发大量的GC操作,甚至会引起丢帧,即卡顿现象。经典场景是在for循环中new对象,或者是在onDraw()方法中new Paint()导致。
这种现象可以在Memory Minotor
中查看到。
2. 内存溢出OOM概念
引起OOM的原因有两种:
内存泄露导致
大量无法被回收的内存一直占据堆内存,导致再给对象分配内存时抛出异常。
这里一定要小心那些几K的内存泄露,因为操作是不断进行的,累积下来就会占用很多。总之要避免内存泄露的发生。滥用内存导致
比如显示一张很大的图片,直接抛出异常。这种情况比较好处理,直接在该代码处做处理就行。
接下来就是使用工具来检测内存泄露了。
3. 内存分析工具
分析内存使用情况,主要是为了避免内存泄露,因为在编码中最不应该发生的情况就是内存泄露,保证了这一点才能进行其他方面的优化。
但这里并不介绍如何使用这些工具,毕竟工具越用越熟。
命令行
adb shell dumpsys meminfo -a packageName
AS的Memory窗口
Memory Monitorleakcanary神器
HPROF Viewer and Analyzer
To take and display a snapshot of the Java heap, see HPROF Viewer and Analyzer.Allocation Tracker
To take and display a snapshot of memory allocation, see Allocation Tracker.MAT工具
3. 怎么使应用最大化的减少占用内存
在消灭了内存泄露后,那么在编码中怎样减少内存的占用。
3.1 减小对象的内存占用
要尽量减少新分配出来的对象占用内存的大小,尽量使用更加轻量的对象。
- 使用更加轻量的数据结构,比如SparseArray、ArrayMap等
- 避免在Android里面使用Enum
- 减小Bitmap对象的内存占用,
- 使用更小的图片
- 优化界面交互过程中频繁的内存使用;譬如在列表等操作中只加载可见区域的Bitmap、滑动时不加载、停止滑动后再开始加载。
- 尽量使用线程池替代多线程操作,这样可以节约内存及CPU占用率。
- 避免创建不必要的对象诸如一些临时对象, 特别是循环中的.
3.2 内存对象的重复利用
大多数对象的复用,最终实施的方案都是利用对象池技术,要么是在编写代码的时候显式的在程序里面去创建对象池,然后处理好复用的实现逻辑,要么就是利用系统框架既有的某些复用特性达到减少对象的重复创建,从而减少内存的分配与回收。
- 复用系统自带的资源
- Bitmap对象的复用
- 利用inBitmap的高级特性提高Android系统在Bitmap分配与释放执行效率上的提升
3.3 内存使用策略优化
- 谨慎使用large heap
- 设置LRU缓存大小时综合考虑设备内存阈值与其他因素设计合适的缓存大小
- 考虑复写onLowMemory()与onTrimMemory()
- Try catch某些大内存分配的操作
- 珍惜Services资源
- 优化布局层次,减少内存消耗
- 谨慎使用“抽象”编程
- 使用nano protobufs序列化数据
- 谨慎使用依赖注入框架
- 使用ProGuard来剔除不需要的代码
- 谨慎使用第三方libraries,去除里面的资源、依赖包等
- 考虑不同的实现方式来优化内存占用
- 尽量的优化自己的代码,减少冗余,进行编译打包等优化对齐处理,避免类加载时浪费内存。
结语
本篇文章介绍讲如何优化内存。首先避免内存泄露,然后在编码中要注意代码即在分配内存,要注意代码质量,减少占用内存。
这三篇文章到这就差不多对内存性能优化有了大概介绍了,希望对大家有帮助,因水平有限,还请斧正。
参考: