上一篇: Android6.0特性
为什么要进行内存优化
APP内存限制,OOM导致APP崩溃
流畅性,响应速度和用户体验会受到影响
如何查看APP可使用的内存
ActivityManager activityManager=(ActivityManager) getSystenService(Context.ACTIVITY_SERVICE);
int memClass=activityManager.getMemoryClass();(以M为单位)
int LargemrnClass=activityManager.getLargeMemoryClass();(以M为单位)
Android的内存管理方式
Android系统内存分配与回收方式
Android系统的底层是linux系统,应用开发使用的框架是Java,一个APP通常就是一个进程对应一个虚拟机
查看进程
adb shell//进入android底层linux系统命令 ps //查看系统里面进程的命令 dumpsys meminfo //进程名: 查看进程内存
GC(Java中的垃圾处理器)只在Heap(堆)剩余空间不够时才发出垃圾回收
- GC触发时,所有的线程都会被暂停
APP的内存限制机制
每个APP分配的内存限制,在不同的设备上是不同的
吃内存大户:图片
为什么要限制?如果不限制,这个APP运行就会影响其他APP的运行
APP内存优化方法
数据结构优化
- 频繁字符串拼接使用StringBuilder
- 使用优化过的数据集合 (使用SparseArray,SparseBooleanArray替代Array。ArrayMap,SparseArray替代HashMap)
- 内存抖动:突然申请很多内存空间,马上用完就不用,过了一会就又申请了内存,马上用完又不用,长时间会影响APP的运行。例如:在循环语句中,new新的对象。
- 使用枚举会比使用静态变量消耗两倍以上的内存,尽可能不使用枚举
- 任何一个java类,包括:内部类,匿名类,都要占用大概500字节的内存空间。
- 任何一个类的实例都消耗12-16字节的内存开支,因此频繁的创建实例也是会一定的程度上影响内存
- 在使用HashMap时,即时你只设置了一个基本数据类型的键,比如int,但是也会按照对象的大小来分配内存,是32字节,我不是4字节。因此最好的办法是就像上面所说的一样,使用优化过的数据集合。
- 在系统吃紧时可能已经无法维护正在运行的Service所依赖的进程,为了能控制Service的生命周期,Android官方推荐最佳的解决方案就是使用IntentService,这种Service后台任务执行结束后会自动停止,从而极大程度上避免了Service内存泄漏的可能性。(让一个Service在后台一直保持运行,即时它不执行热河工作,这是编写Android程序最糟糕的做法之一。)
当界面不可见时释放内存:在Activity中重写onTrimMemory()方法,然后在这个方法中监听TRIM_MEMORY_UI_HIDDEN这个级别,就说明用户已经离开了我们的程序,那么此时就可以进行资源释放造作的。
@Override public void onTrimMemory(int level){ super.onTrimMemory(level) switch(level){ case TRIM_MEMORY_UI_HIDDEN: //进行资源释放的操作 break; } }
对象复用:
- 复用系统自带的资源
- listView/GridView的ConvertView的复用
- 避免在onDraw方法里执行对象的创建(影响View绘制的时间 ,如果时间比较长,会比较卡顿,运行不流畅,把对象放在外面。)
避免内存泄漏
- 一个不使用的资源无法进行回收
- 内存泄漏会导致剩余可用的Heap越来越少,频发触发GC
- 用Appliction Context 而不是Activity Context
- 注意Cursor对象是否关闭