Android系统内存分配与回收方式
adb shell 进入安卓底层Linux系统命令
ps 查看系统中进程
dumpsys meminfo com.xxx.xxx 查看进程相关信息
Pss Total 物理内存
- 一个App通常就是一个进程对应一个虚拟机
- GC只在Heap剩余空间不够时才触发垃圾回收
- GC触发时,所有的线程都是暂停的
APP内存限制
1、 每个App分配的最大内存限制,随不同设备而不同
Android 中是有App的运行内存限制,如果不进行内存优化,容易 产生OOM导致App崩溃。
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int memClass = activityManager.getMemoryClass();
int largeMemClass = activityManager.getLargeMemoryClass();
memClass手机中为一个App进程所分配的内存大小 M为单位
largeMemClass是最大内存
2、 吃内存大户:图片
切换应用时后台APP清理机制
- APP切换时的LRU Cache
- onTrimMemory()回调方法
监控内存的几种方法
1 代码监控
float totalMemory = Runtime.getRuntime().totalMemory() * 1.0f / (1024 * 1024);
float freeMemory = Runtime.getRuntime().freeMemory() * 1.0f / (1024 * 1024);
float maxMemory = Runtime.getRuntime().maxMemory() * 1.0f / (1024 * 1024);
totalMemory App目前使用的内存
freeMemory App闲置内存
maxMemory 系统为App分配的最大内存
2 Android Monitor
Android studio中提供的可视监控
APP内存优化方法
数据结构优化
1、 频繁字符串拼接使用StringBuilder
字符串使用+的方式进行拼接,相当于创建了新的对象,存储在堆区。并且相比较StringBuilder非常耗时。
2、 ArrayMap、SparseArray 替代HashMap
3、内存抖动
在短时间内申请大量内存空间,又很快不再使用,触动GC回收,GC触发时,所有的线程都是暂停的。如果这个情况在短时间内多次发生,就会出现内存抖动,影响用户体验。
4、再小的Class会耗费0.5KB
对象复用
1、复用系统自带的资源
2、ListView和GridView的ConvertView复用
3、避免在onDraw方法里执行对象的创建
避免内存泄漏方法
内存泄漏是由于代码问题,导致这块内存虽然已经不再使用了,但是仍然被其他东西引用着,使得GC没办法对它进行回收操作。
而内存泄漏会导致剩余可用的Heap越来越少,会频繁地触发GC,GC又没有办法回收,最终可能会导致OOM。
尽量使用Application Context而不是Activity Context
注意Cursor对象是否及时关闭
OOM问题优化
OOM问题分析
OOM绝大多数是图片引起的,上面内存泄漏也有讲到OOM
强引用、软引用的意义
强引用:就是我们平时使用的New之类的创建出来的对象,强引用的生命周期是跟所在Activity或者所在方法的生命周期相同,Activity销毁或方法执行完毕,强引用就可以被GC回收。而在Activity内存空间不足的时候,GC也无法回收强引用。
软引用:SoftReference 在Activity内存空间不足的时候,GC可以回收软引用所占用的内存空间。
优化OOM问题的方法
1、注意临时Bitmap对象的及时回收
2、避免Bitmap的浪费
3、Try catch某些大内存分配的操作
4、加载Bitmap:缩放比例,解码格式,局部加载(可以使用LRU算法和软引用来处理大量图片加载)