1、为什么进行内存优化(如果不进行内存优化)
APP运营内存限制,OOM导致APP崩溃
APP性能,流畅性,响应速度和体验
2、Android内存管理方式:
Android系统内存分配与回收方式
APP内存限制机制
切换应用时,后台APP清理机制
监控内存的几种方法演示
2.1 Android系统内存分配与回收方式
相关命令行:
ps,查看进程pid,ppid
,启动的进程,init->zygote->remusic
查看:dumpsys meminfo com.wm.remusic
pss物理内存
Heap堆的尺寸
NativeHeap相当于JNI开发方式下 XX空间下的堆
DalvikHeap虚拟内存
堆栈
共享内存
apk占用内存
直观看到一个APP通常就是一个进程对称一个虚拟机
GC只在Heap剩余空间不够时才触发垃圾回收,释放空间。
GC触发时,所有县城都是会被暂停,所以会存在内存抖动
2.2 APP内存限制机制
每个APP分配的最大内存限制,随不同设备而不同
吃内存大户:图片
我什么要限制?因为是多任务系统,需要协作运行
2.3切换应用时,后台APP清理机制
分时复用
APP切换时使用LRU Cache
onTrimMemory()回调方法,及时释放不需要的内存,减小app占用内存,减少系统清理app的可能性
2.4 监控内存的几种方法演示
AS代码
private void calculate() {
StringBuilder strBuilder =new StringBuilder();
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int memClass =activityManager.getMemoryClass();//m为单位
int largeMemClass=activityManager.getLargeMemoryClass();//以m为单位
strBuilder.append("memClass:"+ memClass + "\n");
strBuilder.append("largememClass:"+ largeMemClass + "\n");
Float totalMemory=Runtime.getRuntime().totalMemory()*1.0f /(1024*1024);
Float freelemory =Runtime.getRuntime().freeMemory()*1.0f /(1024*1024);
Float maxlemory=Runtime.getRuntime().maxMemory()*1.0f /(1024*1024);
info.setText(strBuilder.toString());
Log.d("打印内存", strBuilder.toString());
}
AS自带内存监控工具:
3、APP内存优化方法
数据结构
对象复用
内存泄漏
相关演示
3.1 数据结构优化
1、频繁字符串拼接用StringBuilder,效率和耗时对比StringBuild更好
2、ArrayMap, SparseArray替换HashMap
3、内存抖动:突然间申请很多变量和空间后再释放,且GC时所有进程会暂停,重复此行为。
例如:优化方案:将变量strlatrix放在循环外
private void doChurn(){
Log.d("mooc", "doChurn start:");
for(int i=0; i< rowlength; i++) {
String[] strlatrix = new String[length]; // 主要在这里,不停的重新申请变量
for(int j=0;j< length; j++) {
strlatrix[j]= String.value0f(ran.nextDouble()); //使用后,释放空间,造成不停的申请、释放大量空间,引起抖动
}
Log.d("mooc", "doChurn rowStr:"+i);
}
Log. d("mooc","doChurn rowStr end:");
}
// 优化方案:将变量strlatrix放在循环外
4、再小的Class耗费0.5KB
5、HashMap的一个entry需要额外占用32B
3.2 对象复用
复用系统自带的资源;
ListView、GrideView的ConvertView的复用,recycleView的适配器也可复用,等等等;
避免在onDraw方法里面执行对象的创建,onDraw界面,图像,view有变动,则会重新执行onDraw,如果在里面进行对象创建,则会影响绘制时间,如果onDraw绘制时间较长,则会引起UI卡顿,且onDraw频繁执行,创建也会频繁执行;
3.3内存泄漏
内存泄漏:代码有瑕疵,导致内存停止不用,但被其他变量引用,导致GC无法回收。
导致剩余可用Heap越来越少,频繁触发GC;
典型例子:在一个activity中有一个比较耗时的线程,当推出activity时,线程依然在执行,无法回收内存,导致了内存泄漏;
建议:用Application Context而不是用Activity Context;
注意Cursor对象是否及时关闭;
4、OOM(内存溢出)问题优化
问题分析
强引用、软引用的意义
优化OOM问题方法
4.1 OOM问题分析
OOM必然性与可解决性
OOM绝大部分发生在图片
4.2 强引用、软引用
public class Gate extends AppCompatActivityprivate {
private String strongref;
private SoftReference<String> softref;
@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gate);
strongref = String.valueOf(Math.random()); // 在生命周期中,不会被回收
softref=new SoftReference(String.valueOf(Math.random())); //在生命周期中,内存不够会被回收
...
}
}
4.3 onTrimMemory内存变换情况:
ComponentCallbacks2 | Android Developers (google.cn)
The values provided by onTrimMemory(int) do not represent a single linear progression of memory limits, but provide you different types of clues about memory availability:
- When your app is running:
a.TRIM_MEMORY_RUNNING_MODERATE
b.TRIM_MEMORY_RUNNING_LOW
c.TRIM_MEMORY_RUNNING_CRITICAL
- When your app's visibility changes:
a.TRIM_MEMORY_UI_HIDDEN
- When your app's process resides in the background LRU list:
a.TRIM_MEMORY_BACKGROUND
b.TRIM_MEMORY_MODERATE
c.TRIM_MEMORY_COMPLETE
To support API levels lower than 14, you can use the ComponentCallbacks.onLowMemory() method as a fallback that's roughly equivalent to the ComponentCallbacks2#TRIM_MEMORY_COMPLETE level.
4.4 优化OOM问题方法
注意临时Bitmap对象的及时回收,调用recycle();
避免Bitmap的浪费;
TryCatch某些大内存分配操作;
加载Bitmap:缩放比例,解码格式,局部加载;
代码:暂时不写。
走过路过,麻烦关注下微信公众号,不胜感激~
微信公众号链接: Android性能优化-内存优化