一、性能优化
TraceView性能分析工具
TraceView: ddms中的一个分析工具
使用方式 start method profiling 开始跟踪 stop method profiliing 结束跟踪
按方法调用消耗时间的降序排列,分析耗时较多的方法是否有优化的空间;
二、内存优化
内存溢出(out of memory):简称oom是指程序在申请内存空间后,没有足够的内存空间供其使用
内存泄漏(memory leak):是指程序在申请内存空间后,无法释放已申请的内存空间。
程序加载到手机内存中,数据挤爆内存称为oom,数据引用无法得到释放称为内存泄露
内存溢出:编译的时候就会报错,这个好解决,一般都是加载大图,或者大数据
内存泄露:运行的时候,没有报错,程序正常运行,但是运行多边,就会卡顿,或者蹦掉。
可以用使用工具来检查:leakcanary
1.使用方法
添加依赖:
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
Application中初始化:
public class ExampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 初始化LeakCanary
if (LeakCanary.isInAnalyzerProcess(this)) {
return;
}
LeakCanary.install(this);
// Normal app init code...
}
}
运行之后,打开你要检查的app,随意点击,会有弹框出现,有消息显示内存泄漏。
常见你的内存泄漏情况:
1.静态变量的使用(静态变量直接或者间接地引用了Activity对象会造成内存泄漏)
Activity定义成了静态变量(activity静态变量直接加载到内存中,然而突然app关闭当前activity,内存中还有引用指向activity,造成了内存泄漏)
Activity中使用了静态的View(View会持有Activity的对象引用)(静态的view也是开始的时候加载到内存中,每当activity中关闭的时候,view的引用还在内存空间中,没有得到释放,就会造成内存泄漏)
ImageSpan引用了Activity Context
单例引用了Activity Context(单例同样是静态的,引用了activity的引用)
2.线程(包括AsyncTask)的使用:Activity退出后线程还在运行,并且线程中使用了Activity或View对象
3.Handler对象的使用:Activity退出后Handler仍有消息要处理;(Handler接收子线程中发过来的消息,应该是activity退出后,Handler也要取消,消息不再接收,引用释放掉,handler的轮询器在内存中运行,activity没有关闭后,没有释放handler,handler还有activity的引用)
4.广播接收者没有注销;服务没有解绑;游标关闭,流关闭
5.在Activity中创建了非静态内部类(内部类中直接或者间接引用到了Activity)的静态变量
6.静态集合保存的对象没有及时清除;(LeakCanary分析不了,使用DDMS及MAT)
注意在Java中,非静态(匿名)内部类会引用外部类对象,而静态内部类不会引用外部类对象。
通过DDMS和MAT工具分析,操作步骤如下:
通过DDMS(或者AS的monitor -> memery窗口)发现问题: 通过AS中的Monitor窗口进行分析,查看内存分配情况,如果操作应用时内存一直往上涨说明可能存在内存泄漏。
通过MAT定位问题: 使用 Memory Analyzer tool(MAT)
使用: 需要生成一个hprof文件,再使用hprof-conv.exe对hprof文件进行处理, 再用MAT打开该文件进行分析
hprof-conv.exe工具的使用
hprof-conv a.hprof b.hprof